This is an R Notebook which describes the distant reading process used for my project. There are brief descriptors above each code chunk which describe what was done, with more detailed commentary in the coding sections which are noted with a “#” sign. Downloading the whole folder “Neural Network Usage in Science” and opening in Studio R will let you run this code on your own.

Once the database was downloaded, according to the specification in the methodology section, I load all the databases from different years. I dropped the columns that weren’t of interest and renamed those that were for easier use. Just incase of duplicates, I extracted the unique instances of rows. I discarded duplicate rows and columns that contained no information at all. I created a unique ID per article to make identifying specific articles easier to find if necessary. When data wasn’t available, Scopus used a text of “[x category is not available]” instead of just “NA”. To convert to NA sections, I filtered for rows that contained “available]” and copied the message precisely. That way I equated the message to an “NA” text for easier usage.

#loading the necesary packages for this code
library(dplyr)
library(tidyr)
library(ggplot2)
library(readr)
library(stringr)
library(skimr)
library(splitstackshape)
library(janitor)
library(jcolors)
library(wordcloud)
library(wordcloud2)
library(tm)
library(data.table)

#loading the csv files and then joining them in to one data base
  ##converting blanks in to NA

#2010 data bases
data.10.o <- read.csv ("2010_no_articles.csv", na.strings = c("", "NA"))
data.10.a <- read.csv ("2010_yes_articles.csv", na.strings = c("", "NA"))

#2011 data bases
data.11.o <- read.csv ("2011_no_articles.csv", na.strings = c("", "NA"))
data.11.a <- read.csv ("2011_yes_articles.csv", na.strings = c("", "NA"))

#2012 databases
data.12.o <- read.csv ("2012_no_articles.csv", na.strings = c("", "NA"))
data.12.a <- read.csv ("2012_yes_articles.csv", na.strings = c("", "NA"))

#2013 databases
data.13.o <- read.csv ("2013_no_articles.csv", na.strings = c("", "NA"))
data.13.a <- read.csv ("2013_articles.csv", na.strings = c("", "NA"))

#2014 databases
data.14.a <- read.csv ("2014_articles.csv", na.strings = c("", "NA"))
data.14.o <- read.csv ("2014_other.csv", na.strings = c("", "NA"))

#2015 databases
data.15.a <- read.csv ("2015_articles.csv", na.strings = c("", "NA"))
data.15.o <- read.csv ("2015_other.csv", na.strings = c("", "NA"))

#2016 database
  ## everything fit in one for 2016
data.16.all <- read.csv ("2016_all.csv", na.strings = c("", "NA"))

#2017 database
  ## everything fir in one for 2017
data.17.all <- read.csv ("2017_all.csv", na.strings = c("", "NA"))

#2018 database
data.18.a <- read.csv ("2018_articles.csv", na.strings = c("", "NA"))
data.18.o <- read.csv ("2018_other.csv", na.strings = c("", "NA"))

#2019 database
data.19.a <- read.csv ("2019_articles.csv", na.strings = c("", "NA"))
data.19.n <- read.csv ("2019_notes.csv", na.strings = c("", "NA"))
data.19.o <- read.csv ("2019_other.csv", na.strings = c("", "NA"))

#2020 database
data.20.n <- read.csv ("2020_notes.csv", na.strings = c("", "NA"))
data.20.o <- read.csv ("2020_other_articles.csv", na.strings = c("", "NA"))

#putting the databases together into one
data.original <- rbind(data.10.a, data.10.o,
          data.11.a, data.11.o, 
          data.12.a, data.12.o, 
          data.13.a, data.13.a,
          data.14.a, data.14.o,
          data.15.a, data.15.o,
          data.16.all,
          data.17.all,
          data.18.o, data.18.a,
          data.19.a, data.19.n, data.19.o,
          data.20.n, data.20.o)

#cleaning the csv file
  ## discarding some of the columns that won't be used
  ## renaming the column titles so they're not capitalized
  ## converting lack of information notes in to NA strings
  ## adding an id to each column

data.original <- data.original %>%
 select(-Art..No., -Molecular.Sequence.Numbers, -Chemicals.CAS,-Tradenames, -Manufacturers, -Funding.Text.1, -Funding.Text.2, -Funding.Text.3, -Funding.Text.4, -Funding.Text.5, -Funding.Text.6, -Funding.Text.7, -Funding.Text.8, -Funding.Text.9, -Funding.Text.10, -Correspondence.Address,  -Abbreviated.Source.Title)

#renaming the columns for easier handling
names(data.original) <- c("authors", "author.id", "title", "year", "source.title", "volume", "issue", "page.start", "page.end", "page.count", "cited.by", "doi", "link", "affiliations", "author.affiliations", "abstract", "author.keywords", "index.keywords", "funding.details", "references", "editors", "sponsors", "publisher", "conference.name", "conference.date", "conference.location", "conference.code", "issn", "isbn", "coden", "pubmed.id", "original.language", "document.type", "publication.stage", "open.access", "source", "eid")

#extracting the unique instances
data.original <- unique(data.original)

#checking how many NAs exist within each column
colSums(is.na(data.original))
            authors           author.id               title                year        source.title 
                  0                   1                   0                   0                   0 
             volume               issue          page.start            page.end          page.count 
                 23                  17                1563                9201               23889 
           cited.by                 doi                link        affiliations author.affiliations 
               6234                 252                   0                7585                 567 
           abstract     author.keywords      index.keywords     funding.details          references 
                  0               23887                1127               16182                9190 
            editors            sponsors           publisher     conference.name     conference.date 
              23889               23889                3149               23889               23889 
conference.location     conference.code                issn                isbn               coden 
              23889               23889                   3               23888                   3 
          pubmed.id   original.language       document.type   publication.stage         open.access 
               9079                   2                   1                   0               15072 
             source                 eid 
                  0                   0 
##UPDATE HERE WHAT THE NUMBERS ARE BEFORE I RUN THEM
  ##RETRACT COLUMNS THAT ARE TOTALLY EMPTY

#all columns (except isbn) are totally empty columns
  #isbn has one 1 row with data
data.original <- data.original %>%
 select(-editors, -sponsors, -conference.name, -conference.date, -conference.location, -conference.code)

#adding a unique id code for all of the columns
data <- data.original %>%
  mutate(id = row_number())

#checking which columns use "[No x available]" format
  ##to be able to copy that format and replace with NA instead

data %>% filter(grepl("available]", authors))
#[No author name available]

data %>% filter(grepl("available]", author.id))
#[No author id available]

#none of these have inserted categories
data %>% filter(grepl("available]", title))
data %>% filter(grepl("available]", year))
data %>% filter(grepl("available]", source.title))
data %>% filter(grepl("available]", volume))
data %>% filter(grepl("available]", issue))
data %>% filter(grepl("available]", page.start))
data %>% filter(grepl("available]", page.end))
data %>% filter(grepl("available]", page.count))
data %>% filter(grepl("available]", cited.by))
data %>% filter(grepl("available]", doi))
data %>% filter(grepl("available]", link))
data %>% filter(grepl("available]", affiliations))
data %>% filter(grepl("available]", author.affiliations))
data %>% filter(grepl("available]", abstract))
#[No abstract available]

data %>% filter(grepl("available]", author.keywords))
data %>% filter(grepl("available]", index.keywords))
data %>% filter(grepl("available]", funding.details))
data %>% filter(grepl("available]", references))
data %>% filter(grepl("available]", publisher))
data %>% filter(grepl("available]", issn))
data %>% filter(grepl("available]", isbn))
data %>% filter(grepl("available]", coden))
data %>% filter(grepl("available]", pubmed.id))
data %>% filter(grepl("available]", original.language))
data %>% filter(grepl("available]", document.type))
data %>% filter(grepl("available]", publication.stage))
data %>% filter(grepl("available]", open.access))
data %>% filter(grepl("available]", source))
data %>% filter(grepl("available]", eid))

#replacing text about missing data for NA instead in the columns that use text to indicate missing information
data <- data %>%
  mutate(authors = na_if(authors, "[No author name available]")) %>%
  mutate(author.id = na_if(author.id, "[No author id available]")) %>%
  mutate(abstract = na_if(abstract, "[No abstract available]"))

To obtain the visualizations about the information of all items in Science from 2010-2020, I calculated the following information: number of issues by year, how many items per volume, and number of items by issue.

#calculating the number of items by issue
number.volumes <- data %>% 
  count(year)
#renaming
names(number.volumes) <- c("year", "n.items.by.year")

#calculating the number of items by issue
number.issues <- data %>% 
  group_by(year) %>%
  count(issue)
#renaming
names(number.issues) <- c("year", "issue", "n.items.by.issue")

#exporting csv file for write up
write.csv(number.issues, "Items_by_issue.csv")

#calculating the number of issue by year
number.issues.by.year <- data %>%
  group_by(year) %>%
  count(issue) %>%
  select(year, issue) %>%
  count(year)

write.csv(number.issues.by.year, "Items_by_year.csv")

#renaming the column to be representative of content, number of items
names(number.issues.by.year) <- c("year", "n.of.issues")

The first graph represents the distribution of items published in science by year.

#graph of the NUMBER OF issues BY YEAR of all science articles 2010-2020
issues.by.year.bar <- ggplot(number.volumes)+
  geom_line(aes(x= year, y = n.items.by.year), color = "#5F8495") +
  scale_x_continuous(breaks = c(2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020)) +
  xlab("Year") + 
  ylab("Number of items") +
  labs(title = "Fig 3. Distribution of amount of items published in science by year, 2010-2020") +
  theme_classic()

issues.by.year.bar

The second figure is a histogram of how many citations articles in Science received from 2010-2020, with a bin width of 30 units.

#visualizing distribution of the citation counts for ALL articles in science
#descriptive visualization
  ## one: histogram of the citation, bins with 30 counts
citation.hist.all <- ggplot(data, aes(x=cited.by)) +
  geom_histogram(fill = "#5F8495", binwidth= 30, center = 0.1) +
  xlab("Number of citations items recieved") + 
  ylab("Number of items") +
  labs(title = "Fig 1. Distribution of number of citations recieved by items 
       published in Science, 2010-2020") +
  theme(plot.title = element_text(size = 11))

citation.hist.all + theme_classic()

Next, I calculated which issue starts each year. That way later I can add year categories to the figure about amount of items published by issue.

#calculating the first issue number of each year to add labels to the later graph
number.issues %>%
  group_by(year) %>%
  slice_head(n = 1)

Using the information gathered above I made a graph of number of items published by issue, noting where each year starts.

#tracking the number of articles about neural networks through the issues in science
issues.by.year.bar <- ggplot(number.issues) +
  geom_line(aes(x= issue, y = n.items.by.issue), color = "#5F8495") +
  scale_x_continuous(breaks = c(5900, 6000, 6100, 6200, 6300, 6400, 6500, 6600, 6700, 6800, 6900)) +
  scale_y_continuous(breaks = c(0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150)) +
  xlab("Issue number") + 
  ylab("Number of items by issue") +
  labs(title = "Fig 2. Distribution of number of items published in Science by issue, 2010-2020")

issues.by.year.bar + theme_classic() +
  #2010
  ggplot2::annotate("segment", x = 5961, xend = 5961, y = 0, yend = 150, linetype = 2, colour = "#5F8495") +
  ggplot2::annotate("text", x = 5961, y = 160, label = "2010", colour = "#5F8495") +
  #2011
  ggplot2::annotate("segment", x = 6013, xend = 6013, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6013, y = 160, label = "2011", color = "#99A799") +
  #2012
  ggplot2::annotate("segment", x = 6064, xend = 6064, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6064, y = 160, label = "2012", color = "#99A799") +
  #2013
  ggplot2::annotate("segment", x = 6115, xend = 6115, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6115, y = 160, label = "2013", color = "#99A799") +
  #2014
  ggplot2::annotate("segment", x = 6166, xend = 6166, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6166, y = 160, label = "2014", color = "#99A799") +
  #2015
  ggplot2::annotate("segment", x = 6217, xend = 6217, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6217, y = 160, label = "2015", color = "#99A799") +
  #2016
  ggplot2::annotate("segment", x = 6268, xend = 6268, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6268, y = 160, label = "2016", color = "#99A799") +
  #2017
  ggplot2::annotate("segment", x = 6320, xend = 6320, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6320, y = 160, label = "2017", color = "#99A799") +
  #2018
  ggplot2::annotate("segment", x = 6371, xend = 6371, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6371, y = 160, label = "2018", color = "#99A799") +
  #2019
  ggplot2::annotate("segment", x = 6422, xend = 6422, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6422, y = 160, label = "2019", color = "#99A799") +
  #2020
  ggplot2::annotate("segment", x = 6473, xend = 6473, y = 0, yend = 150, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6473, y = 160, label = "2020", color = "#99A799")

NA
NA

The next figure is a pie chart of all items published, separated by having abstracts or not having abstracts.

#checking how many articles are missing abstracts
  #total articles missing abstracts = 13210
data.no.abstract <- data %>%
  filter(is.na(abstract)) %>% #filtering those rows in abstract that have NA
  mutate(has.abstract = "No")

data.yes.abstract <- data %>%
  filter(!(id %in% data.no.abstract$id)) %>% #filtering out those articles already categorized as NA
  mutate(has.abstract = "Yes")

data.abstract.both <- rbind(data.no.abstract, data.yes.abstract)

data.abstracts <- data.abstract.both %>%
  group_by(has.abstract) %>%
  count(has.abstract) %>%
  ungroup() %>%
  mutate(per = (100*n)/sum(n))

data.abstracts$per <- round(data.abstracts$per)

ggplot(data.abstracts, aes(x="", y = n, fill = has.abstract)) +
  geom_col() +
  theme_void() +
  theme(axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.title = element_blank(),
        panel.grid = element_blank()) +
  coord_polar("y", start = 0) +
  scale_fill_brewer(palette = "pal5") +
  geom_text(aes(label = paste0(per,"%")), position = position_stack(vjust=0.5)) +
  ggtitle("Fig 4. Percentage of documents with and without abstract information from Science 2010-2020") +
  theme(plot.title = element_text(size = 10)) +
  guides(fill = guide_legend(title = "Has Abstract"))
Unknown palette pal5

This is a distribution of items published in Science by type, stacked by whether they have abstracts or not.

#stacked bar chart about whether different kinds of documents have abstracts or not

all.abstract.types <- ggplot(data.abstract.both, aes(x = document.type, fill = has.abstract)) +
  geom_bar() +
  xlab("Kinds of documents") + 
  ylab("Amount with or without abstract information") +
  theme_classic() +
  scale_fill_brewer(palette = "pal5") +
  ggtitle("       Fig 5. Distribution of Science document types and wether they have abstracts") +
  theme(plot.title = element_text(size = 12)) +
  guides(fill = guide_legend(title = "Has Abstract"))
Unknown palette pal5
#tilting the text so it is readable and moving downwards
all.abstract.types + theme(axis.text.x = element_text(angle = 45, hjust = 1))

To find articles that I deemed to be related to “artificial neural networks” I researched the following keywords (making sure to disregard lower and upper case differences): Neural network, neural networks, artificial neural network, and artificial neural networks. These were chosen because “neural networks” is the MeSH descriptor (medical subject headings from the national library of medicine) and they are usually a standard for setting database keywords. “Artificial neural networks” is the category that seemed to pop up the most in the journal Science itself, the term that as a journal they seem to have agreed on, so I used that as well. I searched those keywords over the following categories: title, abstract, author keywords and index keywords and extracted the articles that did contain that information. I collected 72 articles in total. Also, I separated out columns so that each column had a distinct piece of information over the following categories: author id, author, affiliations, index keywords, references, and author keywords. That way later on I can work with those pieces separately.

# identifying tiles, abstracts, author keywords and index keywords with my own keywords
  ## keywords: Replication crisis, replication crisis, Replicability crisis, replicability crisis, Reproducibility crisis, reproducibility crisis

data.title <- data %>%
  filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", title, ignore.case = TRUE))

data.abstract <- data %>%
  filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", abstract, ignore.case = TRUE))

data.author.keywords <- data %>%
  filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", author.keywords, ignore.case = TRUE))

data.index.keywords <- data %>%
  filter(grepl("Neural network|Neural networks|artificial neural network|artificial neural networks", index.keywords, ignore.case = TRUE))

#BINDING WITH THE EXTRA COLUMNS
#putting all of the categories back together 
data.networks <- do.call("rbind", list(data.title, data.abstract, data.author.keywords, data.index.keywords))

#deleting any articles that might have replicated
data.networks <- data.networks %>%
  distinct(id, .keep_all = TRUE)

#splitting author.id, 
  ##in to separate columns using the splitstackshape library, which doesn't require you to know the total a column needs to be split in

data.networks <- cSplit(data.networks, "author.id", sep=";")

data.networks <-  cSplit(data.networks, "authors", sep=",")
  
data.networks <-  cSplit(data.networks, "affiliations", sep=";")

data.networks <- cSplit(data.networks, "index.keywords", sep=";")
  
data.networks <- cSplit(data.networks, "references", sep=";")

data.networks <- cSplit(data.networks, "author.keywords", sep=";")

The fist figure shows what year items relating to neural networks are published in Science from 2010-2020.

#number of items by year 
number.volumes.networks  <- data.networks %>%
  count(year)

#renaming
names(number.volumes.networks) <- c("year", "n.items.by.year")

#calculating the number of items by issue
number.issues.networks <- data.networks %>% 
  group_by(year) %>%
  count(issue)
#renaming
names(number.issues.networks) <- c("year", "issue", "n.items.by.issue")

#looking at the ARTICLE information by year
issues.by.year.bar.networks <- ggplot(number.volumes.networks) +
  geom_line(aes(x= year, y = n.items.by.year), color = "#5F8495") +
  scale_x_continuous(breaks = c(2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020)) +
 # scale_y_continuous(breaks = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) +
  xlab("Year") + 
  ylab("Number of items") +
  #labs(title = "") +
  theme_classic()

issues.by.year.bar.networks

The next figure visualizes the number of items published in Science relating to neural networks by issue, also indicated by year.

#counting number of articles related to neural networks by issue (54)
issues.of.networks <- data.networks %>%
  group_by(issue) %>%
  count(issue, .drop = FALSE)

#getting a list of all issues (569)
all.issues <- number.issues %>%
  ungroup() %>%
  select(-year, -n.items.by.issue) %>%
  mutate(n = 0)

#filtering out the issues that have neural network information in them  (515/512)
number.issues.networks <- all.issues %>%
  filter(!(issue %in% issues.of.networks$issue))

#adding the databases above together (counted articles related to neural networks and the ones that don't, with 0 numbers)
year.count <- rbind(number.issues.networks, issues.of.networks)

issues.by.year.bar <- ggplot(year.count) +
  geom_line(aes(x= issue, y = n), color = "#406343") +
  scale_y_continuous(breaks = c(0, 1, 2, 3, 4, 5, 6)) +
  scale_x_continuous(breaks = c(5900, 6000, 6100, 6200, 6300, 6400, 6500, 6600, 6700, 6800, 6900)) +
  xlab("Issue number") + 
  ylab("Number of items") +
  ggtitle("Fig 6. Number of published items related to neural networks by issue in Science, 2010-2020") +
  theme(plot.title = element_text(size = 12)) +
  #20109
  ggplot2::annotate("segment", x = 5961, xend = 5961, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 5961, y = 6, label = "2010", color = "#99A799") +
  #2011
  ggplot2::annotate("segment", x = 6013, xend = 6013, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6013, y = 6, label = "2011", color = "#99A799") +
  #2012
  ggplot2::annotate("segment", x = 6064, xend = 6064, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6064, y = 6, label = "2012", color = "#99A799") +
  #2013
  ggplot2::annotate("segment", x = 6115, xend = 6115, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6115, y = 6, label = "2013", color = "#99A799") +
  #2014
  ggplot2::annotate("segment", x = 6166, xend = 6166, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6166, y = 6, label = "2014", color = "#99A799") +
  #2015
  ggplot2::annotate("segment", x = 6217, xend = 6217, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6217, y = 6, label = "2015", color = "#99A799") +
  #2016
  ggplot2::annotate("segment", x = 6268, xend = 6268, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6268, y = 6, label = "2016", color = "#99A799") +
  #2017
  ggplot2::annotate("segment", x = 6320, xend = 6320, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6320, y = 6, label = "2017", color = "#99A799") +
  #2018
  ggplot2::annotate("segment", x = 6371, xend = 6371, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6371, y = 6, label = "2018", color = "#99A799") +
  #2019
  ggplot2::annotate("segment", x = 6422, xend = 6422, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6422, y = 6, label = "2019", color = "#99A799") +
  #2020
  ggplot2::annotate("segment", x = 6473, xend = 6473, y = 0, yend = 5.7, linetype = 2, color = "#99A799") +
  ggplot2::annotate("text", x = 6473, y = 6, label = "2020", color = "#99A799")
  
issues.by.year.bar + theme_classic()

Next is a histogram of number of citations recieved by neural network items from Science 2010-2020.

#descriptive visualization
  ## one: histogram of the citation, bins with 30 counts
citation.hist <- ggplot(data.networks, aes(x=cited.by)) +
  geom_histogram(fill = "#406343", binwidth= 30, center = 0.1) +
  scale_x_continuous(breaks = c(0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900)) +
  xlab("Citation counts") + 
  ylab("Number of articles") +
  labs(title = "Fig 8. Distribution of amount of citations received by neural network items")

citation.hist + theme_classic()

To view the histogram distribution more clearly, I also ran a version that excluded the outliers (which I categorizes as over 500 citations)

#two: visualization of the citation counts excluding outliers (<500)
  ## binwidth 10
data.networks.citation.most <- data.networks %>%
  filter(cited.by < 500)

citation.hist.most <- ggplot(data.networks.citation.most, aes(x=cited.by)) +
  geom_histogram(binwidth = 30, fill = "#406343") +
   # scale_x_continuous(breaks = c(10, 50, 100, 150, 200, 250, 300, 350, 400, 
    #                              450, 500, 550, 600, 650, 700, 750, 800)) +
  xlab("Citation counts, without outliers") + 
  ylab("Number of articles") +
  labs(title = "Fig 9. Distribution of ammount of citations recieved by neural network items, excluding outliers (500)") +
  theme(plot.title = element_text(size = 11))

citation.hist.most + theme_classic()

The following pie chart categorizes what items have or do not have abstract information.

#pie chart of the percentage of articles with no articles

#checking how many articles are missing abstracts
  #total articles missing abstracts = 13210
data.nn.no.abstract <- data.networks %>%
  filter(is.na(abstract)) %>% #filtering those rows in abstract that have NA
  mutate(has.abstract = "No")

data.nn.yes.abstract <- data.networks %>%
  filter(!(id %in% data.nn.no.abstract$id)) %>% #filtering out those articles already categorized as NA
  mutate(has.abstract = "Yes")

data.nn.abstract.both <- rbind(data.nn.no.abstract, data.nn.yes.abstract)

data.nn.abstracts <- data.nn.abstract.both %>%
  group_by(has.abstract) %>%
  count(has.abstract) %>%
  ungroup() %>%
  mutate(per = (100*n)/sum(n))

data.nn.abstracts$per <- round(data.nn.abstracts$per)

ggplot(data.nn.abstracts, aes(x="", y = has.abstract, fill = has.abstract, palette = "BuGn")) +
   geom_col() +
  theme_void() +
  theme(axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.title = element_blank(),
        panel.grid = element_blank()) +
  coord_polar("y", start = 0) +
  scale_fill_brewer(palette = "pal5") +
  geom_text(aes(label = paste0(per,"%")), position = position_stack(vjust=0.5)) +
  ggtitle("Fig 10. Percentages of items about neural networks 
          with or without abstracts in Science 2010-2020") +
  theme(plot.title = element_text(size = 12)) +
  guides(fill = guide_legend(title = "Has Abstract"))
Unknown palette pal5

The next figure is a distribution of document types about neural networks and whether they have abstracts in Science 2010-2020.

#checking by document type what things are missing abstracts
nn.abstract.types <- ggplot(data.nn.abstract.both, aes(x = document.type, fill = has.abstract, palette = "BuGn")) +
  geom_bar() +
  xlab("Kinds of documents") + 
  ylab("Amount with or without abstract information") +
  theme_classic() +
  scale_fill_brewer(palette = "BuGn") +
  guides(fill = guide_legend(title = "Has Abstract")) +
  ggtitle("Fig 11. Distribution of document types about neural networks and wether 
          they have abstracts in Science 2010-2020") +
  theme(plot.title = element_text(size = 12))

#tilting the text so it is readable and moving downwards
nn.abstract.types + theme(axis.text.x = element_text(angle = 45, hjust = 1))

The next figure is a word cloud of the most common words in the abstract, including common words.

#making a long list of all the keywords used in articles about neural networks
index.keywords <- data.networks %>%
  select(index.keywords_01:index.keywords_66, id)

index.keywords = melt(index.keywords,id.vars=c("id"))

#making everything lowercase
index.keywords$value = tolower(index.keywords$value)

index.keywords <- index.keywords %>%
  select(-id, -variable) %>%
  drop_na(value) %>%
  count(value)

wordcloud(words = index.keywords$value, freq = index.keywords$n, min.freq = 5,
          max.words=200, random.order=FALSE, rot.per=0.35,
          colors=brewer.pal(8, "Dark2"), scale=c(2.0,0.25))

To more clearly see the words of interest, I excluded some of the words that are more common in the English language and therefore might be less indicative of what the abstracts are about. The keywords I excluded were: the, of, and, in, a, to, for, that, we, is, by, with, this, are, on, an, can, from, all, ©, be, which, how, or, our, it.

#making wordcloud of the abstract information
abstract.words <- data.networks %>%
  select(id, abstract) %>%
  drop_na(abstract)

#taking away punctuation
abstract.words$abstract <- gsub('[[:punct:] ]+',' ', as.character(abstract.words$abstract))
  
#making whole text lowercase
abstract.words$abstract = tolower(abstract.words$abstract)

#separating column out in to individual words
abstract.words <- cSplit(abstract.words, "abstract", sep=" ")

#trimming leading and trailing whitespace
trimws_df <- function(x, ...){
  x[] <- lapply(x, trimws, ...)
  x
}
abstract.words <- trimws_df(abstract.words)

#combining in to one column
abstract.words = melt(abstract.words, id.vars=c("id"))

#counting the number of words
abstract.words <- abstract.words %>%
  select(-id, -variable) %>%
  drop_na(value) %>%
  count(value)

#making a word cloud including all the words
wordcloud(words = abstract.words$value, freq = abstract.words$n, min.freq = 3,
          max.words=200, random.order=FALSE, rot.per=0.35, scale=c(5.0,0.5),
          colors=brewer.pal(8, "Dark2"))


#removing common words
abstract.words <- abstract.words[!grepl("the|of|and|in|a|to|for|that|we|is|by|with|this|are|on|an|can|from|all|©|be|which|how|or|our|it", abstract.words$value),]

#making word cloud
wordcloud(words = abstract.words$value, freq = abstract.words$n, min.freq = 3,
         max.words=200, random.order=FALSE, rot.per=0.35,
        colors=brewer.pal(8, "Dark2"), scale=c(3.0,0.25))

I selected 4 articles randomly to qualitatively code. Two were totally random and I got: ⁃ Neural scene representation and rendering, 2018. Vol 360, issue 6394. doi: 10.1126/science.aar6170 ⁃ The biochemical basis of microRNA targeting efficacy, 2019. Vol 366. doi: 10.1126/science.aav1741 One was from the top 25% of citations received (more than 171.5 citations) ⁃ Terrestrial gross carbon dioxide uptake: Global distribution and covariation with climate. doi: 10.1126/science.1184984 One was randomly selected from the year with the most articles about neural networks (2019) ⁃ Machine learning transforms how microstates are sampled, 2019. Vol 365. Issue 6457. doi: 10.1126/science.aay2568 As a note, this will return different articles every time it is run. I’ve selected the articles that appeared the first time.

#randomly selecting articles to close read
  ##note, this will return different articles every time it is run. I've selected the articles that appeared the first time.

#randomly selecting 2 articles from the whole networks database
sample_n(data.networks, 2)
  #selected: Neural scene representation and rendering, 2018. Vol 360, issue 6394. doi: 10.1126/science.aar6170
  #selected: The biochemical basis of microRNA targeting efficacy, 2019. Vol 366. doi: 10.1126/science.aav1741

#randomly selecting 1 article within the top 25% number of citations
  ## extracting the quantiles of the dataset, upper 75% = 171.5
quantile(data.networks$cited.by, na.rm=TRUE)
    0%    25%    50%    75%   100% 
   1.0    8.5   58.5  171.5 1831.0 
data.networks.top.75per <- data.networks %>%
  filter(cited.by > 171.5)

sample_n(data.networks.top.75per,1)
  #selected: Terrestrial gross carbon dioxide uptake: Global distribution and covariation with climate. doi: 10.1126/science.1184984

#randomly selecting 1 article from 2019 (the year with the most articles published)
data.networks.2019 <- data.networks %>%
  filter(year == "2019")

sample_n(data.networks.2019, 1)
  #selected: Machine learning transforms how microstates are sampled, 2019. Vol 365. Issue 6457. doi: 10.1126/science.aay2568
LS0tCnRpdGxlOiAiVXNhZ2Ugb2YgdGVybSAnTmV1cmFsIE5ldHdvcmsnIGluIFNjaWVuY2UgMjAxMC0yMDIwIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIGlzIGFuIFIgTm90ZWJvb2sgd2hpY2ggZGVzY3JpYmVzIHRoZSBkaXN0YW50IHJlYWRpbmcgcHJvY2VzcyB1c2VkIGZvciBteSBwcm9qZWN0LiBUaGVyZSBhcmUgYnJpZWYgZGVzY3JpcHRvcnMgYWJvdmUgZWFjaCBjb2RlIGNodW5rIHdoaWNoIGRlc2NyaWJlIHdoYXQgd2FzIGRvbmUsIHdpdGggbW9yZSBkZXRhaWxlZCBjb21tZW50YXJ5IGluIHRoZSBjb2Rpbmcgc2VjdGlvbnMgd2hpY2ggYXJlIG5vdGVkIHdpdGggYSAiIyIgc2lnbi4gRG93bmxvYWRpbmcgdGhlIHdob2xlIGZvbGRlciAiTmV1cmFsIE5ldHdvcmsgVXNhZ2UgaW4gU2NpZW5jZSIgYW5kIG9wZW5pbmcgaW4gU3R1ZGlvIFIgd2lsbCBsZXQgeW91IHJ1biB0aGlzIGNvZGUgb24geW91ciBvd24uCgpPbmNlIHRoZSBkYXRhYmFzZSB3YXMgZG93bmxvYWRlZCwgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpY2F0aW9uIGluIHRoZSBtZXRob2RvbG9neSBzZWN0aW9uLCBJIGxvYWQgYWxsIHRoZSBkYXRhYmFzZXMgZnJvbSBkaWZmZXJlbnQgeWVhcnMuIEkgZHJvcHBlZCB0aGUgY29sdW1ucyB0aGF0IHdlcmVuJ3Qgb2YgaW50ZXJlc3QgYW5kIHJlbmFtZWQgdGhvc2UgdGhhdCB3ZXJlIGZvciBlYXNpZXIgdXNlLiBKdXN0IGluY2FzZSBvZiBkdXBsaWNhdGVzLCBJIGV4dHJhY3RlZCB0aGUgdW5pcXVlIGluc3RhbmNlcyBvZiByb3dzLiBJIGRpc2NhcmRlZCBkdXBsaWNhdGUgcm93cyBhbmQgY29sdW1ucyB0aGF0IGNvbnRhaW5lZCBubyBpbmZvcm1hdGlvbiBhdCBhbGwuIEkgY3JlYXRlZCBhIHVuaXF1ZSBJRCBwZXIgYXJ0aWNsZSB0byBtYWtlIGlkZW50aWZ5aW5nIHNwZWNpZmljIGFydGljbGVzIGVhc2llciB0byBmaW5kIGlmIG5lY2Vzc2FyeS4gV2hlbiBkYXRhIHdhc27igJl0IGF2YWlsYWJsZSwgU2NvcHVzIHVzZWQgYSB0ZXh0IG9mIOKAnFt4IGNhdGVnb3J5IGlzIG5vdCBhdmFpbGFibGVd4oCdIGluc3RlYWQgb2YganVzdCDigJxOQeKAnS4gVG8gY29udmVydCB0byBOQSBzZWN0aW9ucywgSSBmaWx0ZXJlZCBmb3Igcm93cyB0aGF0IGNvbnRhaW5lZCDigJxhdmFpbGFibGVd4oCdIGFuZCBjb3BpZWQgdGhlIG1lc3NhZ2UgcHJlY2lzZWx5LiBUaGF0IHdheSBJIGVxdWF0ZWQgdGhlIG1lc3NhZ2UgdG8gYW4g4oCcTkHigJ0gdGV4dCBmb3IgZWFzaWVyIHVzYWdlLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2xvYWRpbmcgdGhlIG5lY2VzYXJ5IHBhY2thZ2VzIGZvciB0aGlzIGNvZGUKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoc2tpbXIpCmxpYnJhcnkoc3BsaXRzdGFja3NoYXBlKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoamNvbG9ycykKbGlicmFyeSh3b3JkY2xvdWQpCmxpYnJhcnkod29yZGNsb3VkMikKbGlicmFyeSh0bSkKbGlicmFyeShkYXRhLnRhYmxlKQoKI2xvYWRpbmcgdGhlIGNzdiBmaWxlcyBhbmQgdGhlbiBqb2luaW5nIHRoZW0gaW4gdG8gb25lIGRhdGEgYmFzZQogICMjY29udmVydGluZyBibGFua3MgaW4gdG8gTkEKCiMyMDEwIGRhdGEgYmFzZXMKZGF0YS4xMC5vIDwtIHJlYWQuY3N2ICgiMjAxMF9ub19hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCmRhdGEuMTAuYSA8LSByZWFkLmNzdiAoIjIwMTBfeWVzX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDExIGRhdGEgYmFzZXMKZGF0YS4xMS5vIDwtIHJlYWQuY3N2ICgiMjAxMV9ub19hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCmRhdGEuMTEuYSA8LSByZWFkLmNzdiAoIjIwMTFfeWVzX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDEyIGRhdGFiYXNlcwpkYXRhLjEyLm8gPC0gcmVhZC5jc3YgKCIyMDEyX25vX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4xMi5hIDwtIHJlYWQuY3N2ICgiMjAxMl95ZXNfYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQoKIzIwMTMgZGF0YWJhc2VzCmRhdGEuMTMubyA8LSByZWFkLmNzdiAoIjIwMTNfbm9fYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQpkYXRhLjEzLmEgPC0gcmVhZC5jc3YgKCIyMDEzX2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDE0IGRhdGFiYXNlcwpkYXRhLjE0LmEgPC0gcmVhZC5jc3YgKCIyMDE0X2FydGljbGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4xNC5vIDwtIHJlYWQuY3N2ICgiMjAxNF9vdGhlci5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojMjAxNSBkYXRhYmFzZXMKZGF0YS4xNS5hIDwtIHJlYWQuY3N2ICgiMjAxNV9hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCmRhdGEuMTUubyA8LSByZWFkLmNzdiAoIjIwMTVfb3RoZXIuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQoKIzIwMTYgZGF0YWJhc2UKICAjIyBldmVyeXRoaW5nIGZpdCBpbiBvbmUgZm9yIDIwMTYKZGF0YS4xNi5hbGwgPC0gcmVhZC5jc3YgKCIyMDE2X2FsbC5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojMjAxNyBkYXRhYmFzZQogICMjIGV2ZXJ5dGhpbmcgZmlyIGluIG9uZSBmb3IgMjAxNwpkYXRhLjE3LmFsbCA8LSByZWFkLmNzdiAoIjIwMTdfYWxsLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDE4IGRhdGFiYXNlCmRhdGEuMTguYSA8LSByZWFkLmNzdiAoIjIwMThfYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQpkYXRhLjE4Lm8gPC0gcmVhZC5jc3YgKCIyMDE4X290aGVyLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKCiMyMDE5IGRhdGFiYXNlCmRhdGEuMTkuYSA8LSByZWFkLmNzdiAoIjIwMTlfYXJ0aWNsZXMuY3N2IiwgbmEuc3RyaW5ncyA9IGMoIiIsICJOQSIpKQpkYXRhLjE5Lm4gPC0gcmVhZC5jc3YgKCIyMDE5X25vdGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4xOS5vIDwtIHJlYWQuY3N2ICgiMjAxOV9vdGhlci5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojMjAyMCBkYXRhYmFzZQpkYXRhLjIwLm4gPC0gcmVhZC5jc3YgKCIyMDIwX25vdGVzLmNzdiIsIG5hLnN0cmluZ3MgPSBjKCIiLCAiTkEiKSkKZGF0YS4yMC5vIDwtIHJlYWQuY3N2ICgiMjAyMF9vdGhlcl9hcnRpY2xlcy5jc3YiLCBuYS5zdHJpbmdzID0gYygiIiwgIk5BIikpCgojcHV0dGluZyB0aGUgZGF0YWJhc2VzIHRvZ2V0aGVyIGludG8gb25lCmRhdGEub3JpZ2luYWwgPC0gcmJpbmQoZGF0YS4xMC5hLCBkYXRhLjEwLm8sCiAgICAgICAgICBkYXRhLjExLmEsIGRhdGEuMTEubywgCiAgICAgICAgICBkYXRhLjEyLmEsIGRhdGEuMTIubywgCiAgICAgICAgICBkYXRhLjEzLmEsIGRhdGEuMTMuYSwKICAgICAgICAgIGRhdGEuMTQuYSwgZGF0YS4xNC5vLAogICAgICAgICAgZGF0YS4xNS5hLCBkYXRhLjE1Lm8sCiAgICAgICAgICBkYXRhLjE2LmFsbCwKICAgICAgICAgIGRhdGEuMTcuYWxsLAogICAgICAgICAgZGF0YS4xOC5vLCBkYXRhLjE4LmEsCiAgICAgICAgICBkYXRhLjE5LmEsIGRhdGEuMTkubiwgZGF0YS4xOS5vLAogICAgICAgICAgZGF0YS4yMC5uLCBkYXRhLjIwLm8pCgojY2xlYW5pbmcgdGhlIGNzdiBmaWxlCiAgIyMgZGlzY2FyZGluZyBzb21lIG9mIHRoZSBjb2x1bW5zIHRoYXQgd29uJ3QgYmUgdXNlZAogICMjIHJlbmFtaW5nIHRoZSBjb2x1bW4gdGl0bGVzIHNvIHRoZXkncmUgbm90IGNhcGl0YWxpemVkCiAgIyMgY29udmVydGluZyBsYWNrIG9mIGluZm9ybWF0aW9uIG5vdGVzIGluIHRvIE5BIHN0cmluZ3MKICAjIyBhZGRpbmcgYW4gaWQgdG8gZWFjaCBjb2x1bW4KCmRhdGEub3JpZ2luYWwgPC0gZGF0YS5vcmlnaW5hbCAlPiUKIHNlbGVjdCgtQXJ0Li5Oby4sIC1Nb2xlY3VsYXIuU2VxdWVuY2UuTnVtYmVycywgLUNoZW1pY2Fscy5DQVMsLVRyYWRlbmFtZXMsIC1NYW51ZmFjdHVyZXJzLCAtRnVuZGluZy5UZXh0LjEsIC1GdW5kaW5nLlRleHQuMiwgLUZ1bmRpbmcuVGV4dC4zLCAtRnVuZGluZy5UZXh0LjQsIC1GdW5kaW5nLlRleHQuNSwgLUZ1bmRpbmcuVGV4dC42LCAtRnVuZGluZy5UZXh0LjcsIC1GdW5kaW5nLlRleHQuOCwgLUZ1bmRpbmcuVGV4dC45LCAtRnVuZGluZy5UZXh0LjEwLCAtQ29ycmVzcG9uZGVuY2UuQWRkcmVzcywgIC1BYmJyZXZpYXRlZC5Tb3VyY2UuVGl0bGUpCgojcmVuYW1pbmcgdGhlIGNvbHVtbnMgZm9yIGVhc2llciBoYW5kbGluZwpuYW1lcyhkYXRhLm9yaWdpbmFsKSA8LSBjKCJhdXRob3JzIiwgImF1dGhvci5pZCIsICJ0aXRsZSIsICJ5ZWFyIiwgInNvdXJjZS50aXRsZSIsICJ2b2x1bWUiLCAiaXNzdWUiLCAicGFnZS5zdGFydCIsICJwYWdlLmVuZCIsICJwYWdlLmNvdW50IiwgImNpdGVkLmJ5IiwgImRvaSIsICJsaW5rIiwgImFmZmlsaWF0aW9ucyIsICJhdXRob3IuYWZmaWxpYXRpb25zIiwgImFic3RyYWN0IiwgImF1dGhvci5rZXl3b3JkcyIsICJpbmRleC5rZXl3b3JkcyIsICJmdW5kaW5nLmRldGFpbHMiLCAicmVmZXJlbmNlcyIsICJlZGl0b3JzIiwgInNwb25zb3JzIiwgInB1Ymxpc2hlciIsICJjb25mZXJlbmNlLm5hbWUiLCAiY29uZmVyZW5jZS5kYXRlIiwgImNvbmZlcmVuY2UubG9jYXRpb24iLCAiY29uZmVyZW5jZS5jb2RlIiwgImlzc24iLCAiaXNibiIsICJjb2RlbiIsICJwdWJtZWQuaWQiLCAib3JpZ2luYWwubGFuZ3VhZ2UiLCAiZG9jdW1lbnQudHlwZSIsICJwdWJsaWNhdGlvbi5zdGFnZSIsICJvcGVuLmFjY2VzcyIsICJzb3VyY2UiLCAiZWlkIikKCiNleHRyYWN0aW5nIHRoZSB1bmlxdWUgaW5zdGFuY2VzCmRhdGEub3JpZ2luYWwgPC0gdW5pcXVlKGRhdGEub3JpZ2luYWwpCgojY2hlY2tpbmcgaG93IG1hbnkgTkFzIGV4aXN0IHdpdGhpbiBlYWNoIGNvbHVtbgpjb2xTdW1zKGlzLm5hKGRhdGEub3JpZ2luYWwpKQoKI2FsbCBjb2x1bW5zIChleGNlcHQgaXNibikgYXJlIHRvdGFsbHkgZW1wdHkgY29sdW1ucwogICNpc2JuIGhhcyBvbmUgMSByb3cgd2l0aCBkYXRhCmRhdGEub3JpZ2luYWwgPC0gZGF0YS5vcmlnaW5hbCAlPiUKIHNlbGVjdCgtZWRpdG9ycywgLXNwb25zb3JzLCAtY29uZmVyZW5jZS5uYW1lLCAtY29uZmVyZW5jZS5kYXRlLCAtY29uZmVyZW5jZS5sb2NhdGlvbiwgLWNvbmZlcmVuY2UuY29kZSkKCiNhZGRpbmcgYSB1bmlxdWUgaWQgY29kZSBmb3IgYWxsIG9mIHRoZSBjb2x1bW5zCmRhdGEgPC0gZGF0YS5vcmlnaW5hbCAlPiUKICBtdXRhdGUoaWQgPSByb3dfbnVtYmVyKCkpCgojY2hlY2tpbmcgd2hpY2ggY29sdW1ucyB1c2UgIltObyB4IGF2YWlsYWJsZV0iIGZvcm1hdAogICMjdG8gYmUgYWJsZSB0byBjb3B5IHRoYXQgZm9ybWF0IGFuZCByZXBsYWNlIHdpdGggTkEgaW5zdGVhZAoKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgYXV0aG9ycykpCiNbTm8gYXV0aG9yIG5hbWUgYXZhaWxhYmxlXQoKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgYXV0aG9yLmlkKSkKI1tObyBhdXRob3IgaWQgYXZhaWxhYmxlXQoKI25vbmUgb2YgdGhlc2UgaGF2ZSBpbnNlcnRlZCBjYXRlZ29yaWVzCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHRpdGxlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgeWVhcikpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHNvdXJjZS50aXRsZSkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHZvbHVtZSkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGlzc3VlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgcGFnZS5zdGFydCkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHBhZ2UuZW5kKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgcGFnZS5jb3VudCkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGNpdGVkLmJ5KSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgZG9pKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgbGluaykpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGFmZmlsaWF0aW9ucykpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGF1dGhvci5hZmZpbGlhdGlvbnMpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBhYnN0cmFjdCkpCiNbTm8gYWJzdHJhY3QgYXZhaWxhYmxlXQoKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgYXV0aG9yLmtleXdvcmRzKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgaW5kZXgua2V5d29yZHMpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBmdW5kaW5nLmRldGFpbHMpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCByZWZlcmVuY2VzKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgcHVibGlzaGVyKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgaXNzbikpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIGlzYm4pKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBjb2RlbikpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHB1Ym1lZC5pZCkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIG9yaWdpbmFsLmxhbmd1YWdlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgZG9jdW1lbnQudHlwZSkpCmRhdGEgJT4lIGZpbHRlcihncmVwbCgiYXZhaWxhYmxlXSIsIHB1YmxpY2F0aW9uLnN0YWdlKSkKZGF0YSAlPiUgZmlsdGVyKGdyZXBsKCJhdmFpbGFibGVdIiwgb3Blbi5hY2Nlc3MpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBzb3VyY2UpKQpkYXRhICU+JSBmaWx0ZXIoZ3JlcGwoImF2YWlsYWJsZV0iLCBlaWQpKQoKI3JlcGxhY2luZyB0ZXh0IGFib3V0IG1pc3NpbmcgZGF0YSBmb3IgTkEgaW5zdGVhZCBpbiB0aGUgY29sdW1ucyB0aGF0IHVzZSB0ZXh0IHRvIGluZGljYXRlIG1pc3NpbmcgaW5mb3JtYXRpb24KZGF0YSA8LSBkYXRhICU+JQogIG11dGF0ZShhdXRob3JzID0gbmFfaWYoYXV0aG9ycywgIltObyBhdXRob3IgbmFtZSBhdmFpbGFibGVdIikpICU+JQogIG11dGF0ZShhdXRob3IuaWQgPSBuYV9pZihhdXRob3IuaWQsICJbTm8gYXV0aG9yIGlkIGF2YWlsYWJsZV0iKSkgJT4lCiAgbXV0YXRlKGFic3RyYWN0ID0gbmFfaWYoYWJzdHJhY3QsICJbTm8gYWJzdHJhY3QgYXZhaWxhYmxlXSIpKQpgYGAKClRvIG9idGFpbiB0aGUgdmlzdWFsaXphdGlvbnMgYWJvdXQgdGhlIGluZm9ybWF0aW9uIG9mIGFsbCBpdGVtcyBpbiBTY2llbmNlIGZyb20gMjAxMC0yMDIwLCBJIGNhbGN1bGF0ZWQgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjogbnVtYmVyIG9mIGlzc3VlcyBieSB5ZWFyLCBob3cgbWFueSBpdGVtcyBwZXIgdm9sdW1lLCBhbmQgbnVtYmVyIG9mIGl0ZW1zIGJ5IGlzc3VlLgoKYGBge3J9CiNjYWxjdWxhdGluZyB0aGUgbnVtYmVyIG9mIGl0ZW1zIGJ5IGlzc3VlCm51bWJlci52b2x1bWVzIDwtIGRhdGEgJT4lIAogIGNvdW50KHllYXIpCiNyZW5hbWluZwpuYW1lcyhudW1iZXIudm9sdW1lcykgPC0gYygieWVhciIsICJuLml0ZW1zLmJ5LnllYXIiKQoKI2NhbGN1bGF0aW5nIHRoZSBudW1iZXIgb2YgaXRlbXMgYnkgaXNzdWUKbnVtYmVyLmlzc3VlcyA8LSBkYXRhICU+JSAKICBncm91cF9ieSh5ZWFyKSAlPiUKICBjb3VudChpc3N1ZSkKI3JlbmFtaW5nCm5hbWVzKG51bWJlci5pc3N1ZXMpIDwtIGMoInllYXIiLCAiaXNzdWUiLCAibi5pdGVtcy5ieS5pc3N1ZSIpCgojZXhwb3J0aW5nIGNzdiBmaWxlIGZvciB3cml0ZSB1cAp3cml0ZS5jc3YobnVtYmVyLmlzc3VlcywgIkl0ZW1zX2J5X2lzc3VlLmNzdiIpCgojY2FsY3VsYXRpbmcgdGhlIG51bWJlciBvZiBpc3N1ZSBieSB5ZWFyCm51bWJlci5pc3N1ZXMuYnkueWVhciA8LSBkYXRhICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIGNvdW50KGlzc3VlKSAlPiUKICBzZWxlY3QoeWVhciwgaXNzdWUpICU+JQogIGNvdW50KHllYXIpCgp3cml0ZS5jc3YobnVtYmVyLmlzc3Vlcy5ieS55ZWFyLCAiSXRlbXNfYnlfeWVhci5jc3YiKQoKI3JlbmFtaW5nIHRoZSBjb2x1bW4gdG8gYmUgcmVwcmVzZW50YXRpdmUgb2YgY29udGVudCwgbnVtYmVyIG9mIGl0ZW1zCm5hbWVzKG51bWJlci5pc3N1ZXMuYnkueWVhcikgPC0gYygieWVhciIsICJuLm9mLmlzc3VlcyIpCmBgYAoKVGhlIGZpcnN0IGdyYXBoIHJlcHJlc2VudHMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBpdGVtcyBwdWJsaXNoZWQgaW4gc2NpZW5jZSBieSB5ZWFyLgpgYGB7cn0KI2dyYXBoIG9mIHRoZSBOVU1CRVIgT0YgaXNzdWVzIEJZIFlFQVIgb2YgYWxsIHNjaWVuY2UgYXJ0aWNsZXMgMjAxMC0yMDIwCmlzc3Vlcy5ieS55ZWFyLmJhciA8LSBnZ3Bsb3QobnVtYmVyLnZvbHVtZXMpKwogIGdlb21fbGluZShhZXMoeD0geWVhciwgeSA9IG4uaXRlbXMuYnkueWVhciksIGNvbG9yID0gIiM1Rjg0OTUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMjAxMCwgMjAxMSwgMjAxMiwgMjAxMywgMjAxNCwgMjAxNSwgMjAxNiwgMjAxNywgMjAxOCwgMjAxOSwgMjAyMCkpICsKICB4bGFiKCJZZWFyIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgaXRlbXMiKSArCiAgbGFicyh0aXRsZSA9ICJGaWcgMy4gRGlzdHJpYnV0aW9uIG9mIGFtb3VudCBvZiBpdGVtcyBwdWJsaXNoZWQgaW4gc2NpZW5jZSBieSB5ZWFyLCAyMDEwLTIwMjAiKSArCiAgdGhlbWVfY2xhc3NpYygpCgppc3N1ZXMuYnkueWVhci5iYXIKYGBgCgpUaGUgc2Vjb25kIGZpZ3VyZSBpcyBhIGhpc3RvZ3JhbSBvZiBob3cgbWFueSBjaXRhdGlvbnMgYXJ0aWNsZXMgaW4gU2NpZW5jZSByZWNlaXZlZCBmcm9tIDIwMTAtMjAyMCwgd2l0aCBhIGJpbiB3aWR0aCBvZiAzMCB1bml0cy4KYGBge3J9CiN2aXN1YWxpemluZyBkaXN0cmlidXRpb24gb2YgdGhlIGNpdGF0aW9uIGNvdW50cyBmb3IgQUxMIGFydGljbGVzIGluIHNjaWVuY2UKI2Rlc2NyaXB0aXZlIHZpc3VhbGl6YXRpb24KICAjIyBvbmU6IGhpc3RvZ3JhbSBvZiB0aGUgY2l0YXRpb24sIGJpbnMgd2l0aCAzMCBjb3VudHMKY2l0YXRpb24uaGlzdC5hbGwgPC0gZ2dwbG90KGRhdGEsIGFlcyh4PWNpdGVkLmJ5KSkgKwogIGdlb21faGlzdG9ncmFtKGZpbGwgPSAiIzVGODQ5NSIsIGJpbndpZHRoPSAzMCwgY2VudGVyID0gMC4xKSArCiAgeGxhYigiTnVtYmVyIG9mIGNpdGF0aW9ucyBpdGVtcyByZWNpZXZlZCIpICsgCiAgeWxhYigiTnVtYmVyIG9mIGl0ZW1zIikgKwogIGxhYnModGl0bGUgPSAiRmlnIDEuIERpc3RyaWJ1dGlvbiBvZiBudW1iZXIgb2YgY2l0YXRpb25zIHJlY2lldmVkIGJ5IGl0ZW1zIAogICAgICAgcHVibGlzaGVkIGluIFNjaWVuY2UsIDIwMTAtMjAyMCIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpCgpjaXRhdGlvbi5oaXN0LmFsbCArIHRoZW1lX2NsYXNzaWMoKQpgYGAKCk5leHQsIEkgY2FsY3VsYXRlZCB3aGljaCBpc3N1ZSBzdGFydHMgZWFjaCB5ZWFyLiBUaGF0IHdheSBsYXRlciBJIGNhbiBhZGQgeWVhciBjYXRlZ29yaWVzIHRvIHRoZSBmaWd1cmUgYWJvdXQgYW1vdW50IG9mIGl0ZW1zIHB1Ymxpc2hlZCBieSBpc3N1ZS4KYGBge3J9CiNjYWxjdWxhdGluZyB0aGUgZmlyc3QgaXNzdWUgbnVtYmVyIG9mIGVhY2ggeWVhciB0byBhZGQgbGFiZWxzIHRvIHRoZSBsYXRlciBncmFwaApudW1iZXIuaXNzdWVzICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIHNsaWNlX2hlYWQobiA9IDEpCmBgYAoKVXNpbmcgdGhlIGluZm9ybWF0aW9uIGdhdGhlcmVkIGFib3ZlIEkgbWFkZSBhIGdyYXBoIG9mIG51bWJlciBvZiBpdGVtcyBwdWJsaXNoZWQgYnkgaXNzdWUsIG5vdGluZyB3aGVyZSBlYWNoIHllYXIgc3RhcnRzLgpgYGB7cn0KI3RyYWNraW5nIHRoZSBudW1iZXIgb2YgYXJ0aWNsZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzIHRocm91Z2ggdGhlIGlzc3VlcyBpbiBzY2llbmNlCmlzc3Vlcy5ieS55ZWFyLmJhciA8LSBnZ3Bsb3QobnVtYmVyLmlzc3VlcykgKwogIGdlb21fbGluZShhZXMoeD0gaXNzdWUsIHkgPSBuLml0ZW1zLmJ5Lmlzc3VlKSwgY29sb3IgPSAiIzVGODQ5NSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1OTAwLCA2MDAwLCA2MTAwLCA2MjAwLCA2MzAwLCA2NDAwLCA2NTAwLCA2NjAwLCA2NzAwLCA2ODAwLCA2OTAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDE1LCAzMCwgNDUsIDYwLCA3NSwgOTAsIDEwNSwgMTIwLCAxMzUsIDE1MCkpICsKICB4bGFiKCJJc3N1ZSBudW1iZXIiKSArIAogIHlsYWIoIk51bWJlciBvZiBpdGVtcyBieSBpc3N1ZSIpICsKICBsYWJzKHRpdGxlID0gIkZpZyAyLiBEaXN0cmlidXRpb24gb2YgbnVtYmVyIG9mIGl0ZW1zIHB1Ymxpc2hlZCBpbiBTY2llbmNlIGJ5IGlzc3VlLCAyMDEwLTIwMjAiKQoKaXNzdWVzLmJ5LnllYXIuYmFyICsgdGhlbWVfY2xhc3NpYygpICsKICAjMjAxMAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDU5NjEsIHhlbmQgPSA1OTYxLCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAiIzVGODQ5NSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA1OTYxLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDEwIiwgY29sb3VyID0gIiM1Rjg0OTUiKSArCiAgIzIwMTEKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2MDEzLCB4ZW5kID0gNjAxMywgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2MDEzLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDExIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMgogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYwNjQsIHhlbmQgPSA2MDY0LCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYwNjQsIHkgPSAxNjAsIGxhYmVsID0gIjIwMTIiLCBjb2xvciA9ICIjOTlBNzk5IikgKwogICMyMDEzCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gNjExNSwgeGVuZCA9IDYxMTUsIHkgPSAwLCB5ZW5kID0gMTUwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInRleHQiLCB4ID0gNjExNSwgeSA9IDE2MCwgbGFiZWwgPSAiMjAxMyIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgIzIwMTQKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2MTY2LCB4ZW5kID0gNjE2NiwgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2MTY2LCB5ID0gMTYwLCBsYWJlbCA9ICIyMDE0IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYyMTcsIHhlbmQgPSA2MjE3LCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYyMTcsIHkgPSAxNjAsIGxhYmVsID0gIjIwMTUiLCBjb2xvciA9ICIjOTlBNzk5IikgKwogICMyMDE2CiAgZ2dwbG90Mjo6YW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gNjI2OCwgeGVuZCA9IDYyNjgsIHkgPSAwLCB5ZW5kID0gMTUwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInRleHQiLCB4ID0gNjI2OCwgeSA9IDE2MCwgbGFiZWwgPSAiMjAxNiIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgIzIwMTcKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2MzIwLCB4ZW5kID0gNjMyMCwgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2MzIwLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDE3IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxOAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYzNzEsIHhlbmQgPSA2MzcxLCB5ID0gMCwgeWVuZCA9IDE1MCwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYzNzEsIHkgPSAxNjAsIGxhYmVsID0gIjIwMTgiLCBjb2xvciA9ICIjOTlBNzk5IikgKwogICMyMDE5CiAgZ2dwbG90Mjo6YW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gNjQyMiwgeGVuZCA9IDY0MjIsIHkgPSAwLCB5ZW5kID0gMTUwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgZ2dwbG90Mjo6YW5ub3RhdGUoInRleHQiLCB4ID0gNjQyMiwgeSA9IDE2MCwgbGFiZWwgPSAiMjAxOSIsIGNvbG9yID0gIiM5OUE3OTkiKSArCiAgIzIwMjAKICBnZ3Bsb3QyOjphbm5vdGF0ZSgic2VnbWVudCIsIHggPSA2NDczLCB4ZW5kID0gNjQ3MywgeSA9IDAsIHllbmQgPSAxNTAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICBnZ3Bsb3QyOjphbm5vdGF0ZSgidGV4dCIsIHggPSA2NDczLCB5ID0gMTYwLCBsYWJlbCA9ICIyMDIwIiwgY29sb3IgPSAiIzk5QTc5OSIpCiAgCgpgYGAKClRoZSBuZXh0IGZpZ3VyZSBpcyBhIHBpZSBjaGFydCBvZiBhbGwgaXRlbXMgcHVibGlzaGVkLCBzZXBhcmF0ZWQgYnkgaGF2aW5nIGFic3RyYWN0cyBvciBub3QgaGF2aW5nIGFic3RyYWN0cy4KYGBge3J9CiNjaGVja2luZyBob3cgbWFueSBhcnRpY2xlcyBhcmUgbWlzc2luZyBhYnN0cmFjdHMKICAjdG90YWwgYXJ0aWNsZXMgbWlzc2luZyBhYnN0cmFjdHMgPSAxMzIxMApkYXRhLm5vLmFic3RyYWN0IDwtIGRhdGEgJT4lCiAgZmlsdGVyKGlzLm5hKGFic3RyYWN0KSkgJT4lICNmaWx0ZXJpbmcgdGhvc2Ugcm93cyBpbiBhYnN0cmFjdCB0aGF0IGhhdmUgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIk5vIikKCmRhdGEueWVzLmFic3RyYWN0IDwtIGRhdGEgJT4lCiAgZmlsdGVyKCEoaWQgJWluJSBkYXRhLm5vLmFic3RyYWN0JGlkKSkgJT4lICNmaWx0ZXJpbmcgb3V0IHRob3NlIGFydGljbGVzIGFscmVhZHkgY2F0ZWdvcml6ZWQgYXMgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIlllcyIpCgpkYXRhLmFic3RyYWN0LmJvdGggPC0gcmJpbmQoZGF0YS5uby5hYnN0cmFjdCwgZGF0YS55ZXMuYWJzdHJhY3QpCgpkYXRhLmFic3RyYWN0cyA8LSBkYXRhLmFic3RyYWN0LmJvdGggJT4lCiAgZ3JvdXBfYnkoaGFzLmFic3RyYWN0KSAlPiUKICBjb3VudChoYXMuYWJzdHJhY3QpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyID0gKDEwMCpuKS9zdW0obikpCgpkYXRhLmFic3RyYWN0cyRwZXIgPC0gcm91bmQoZGF0YS5hYnN0cmFjdHMkcGVyKQoKZ2dwbG90KGRhdGEuYWJzdHJhY3RzLCBhZXMoeD0iIiwgeSA9IG4sIGZpbGwgPSBoYXMuYWJzdHJhY3QpKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWVfdm9pZCgpICsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAicGFsNSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHBlciwiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpKSArCiAgZ2d0aXRsZSgiRmlnIDQuIFBlcmNlbnRhZ2Ugb2YgZG9jdW1lbnRzIHdpdGggYW5kIHdpdGhvdXQgYWJzdHJhY3QgaW5mb3JtYXRpb24gZnJvbSBTY2llbmNlIDIwMTAtMjAyMCIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJIYXMgQWJzdHJhY3QiKSkKYGBgCgpUaGlzIGlzIGEgZGlzdHJpYnV0aW9uIG9mIGl0ZW1zIHB1Ymxpc2hlZCBpbiBTY2llbmNlIGJ5IHR5cGUsIHN0YWNrZWQgYnkgd2hldGhlciB0aGV5IGhhdmUgYWJzdHJhY3RzIG9yIG5vdC4KYGBge3J9CiNzdGFja2VkIGJhciBjaGFydCBhYm91dCB3aGV0aGVyIGRpZmZlcmVudCBraW5kcyBvZiBkb2N1bWVudHMgaGF2ZSBhYnN0cmFjdHMgb3Igbm90CgphbGwuYWJzdHJhY3QudHlwZXMgPC0gZ2dwbG90KGRhdGEuYWJzdHJhY3QuYm90aCwgYWVzKHggPSBkb2N1bWVudC50eXBlLCBmaWxsID0gaGFzLmFic3RyYWN0KSkgKwogIGdlb21fYmFyKCkgKwogIHhsYWIoIktpbmRzIG9mIGRvY3VtZW50cyIpICsgCiAgeWxhYigiQW1vdW50IHdpdGggb3Igd2l0aG91dCBhYnN0cmFjdCBpbmZvcm1hdGlvbiIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAicGFsNSIpICsKICBnZ3RpdGxlKCIgICAgICAgRmlnIDUuIERpc3RyaWJ1dGlvbiBvZiBTY2llbmNlIGRvY3VtZW50IHR5cGVzIGFuZCB3ZXRoZXIgdGhleSBoYXZlIGFic3RyYWN0cyIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJIYXMgQWJzdHJhY3QiKSkKCiN0aWx0aW5nIHRoZSB0ZXh0IHNvIGl0IGlzIHJlYWRhYmxlIGFuZCBtb3ZpbmcgZG93bndhcmRzCmFsbC5hYnN0cmFjdC50eXBlcyArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKVG8gZmluZCBhcnRpY2xlcyB0aGF0IEkgZGVlbWVkIHRvIGJlIHJlbGF0ZWQgdG8g4oCcYXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3PigJ0gSSByZXNlYXJjaGVkIHRoZSBmb2xsb3dpbmcga2V5d29yZHMgKG1ha2luZyBzdXJlIHRvIGRpc3JlZ2FyZCBsb3dlciBhbmQgdXBwZXIgY2FzZSBkaWZmZXJlbmNlcyk6IE5ldXJhbCBuZXR3b3JrLCBuZXVyYWwgbmV0d29ya3MsIGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmssIGFuZCBhcnRpZmljaWFsIG5ldXJhbCBuZXR3b3Jrcy4gVGhlc2Ugd2VyZSBjaG9zZW4gYmVjYXVzZSDigJxuZXVyYWwgbmV0d29ya3PigJ0gaXMgdGhlIE1lU0ggZGVzY3JpcHRvciAobWVkaWNhbCBzdWJqZWN0IGhlYWRpbmdzIGZyb20gdGhlIG5hdGlvbmFsIGxpYnJhcnkgb2YgbWVkaWNpbmUpIGFuZCB0aGV5IGFyZSB1c3VhbGx5IGEgc3RhbmRhcmQgZm9yIHNldHRpbmcgZGF0YWJhc2Uga2V5d29yZHMuICJBcnRpZmljaWFsIG5ldXJhbCBuZXR3b3JrcyIgaXMgdGhlIGNhdGVnb3J5IHRoYXQgc2VlbWVkIHRvIHBvcCB1cCB0aGUgbW9zdCBpbiB0aGUgam91cm5hbCBTY2llbmNlIGl0c2VsZiwgdGhlIHRlcm0gdGhhdCBhcyBhIGpvdXJuYWwgdGhleSBzZWVtIHRvIGhhdmUgYWdyZWVkIG9uLCBzbyBJIHVzZWQgdGhhdCBhcyB3ZWxsLiBJIHNlYXJjaGVkIHRob3NlIGtleXdvcmRzIG92ZXIgdGhlIGZvbGxvd2luZyBjYXRlZ29yaWVzOiB0aXRsZSwgYWJzdHJhY3QsIGF1dGhvciBrZXl3b3JkcyBhbmQgaW5kZXgga2V5d29yZHMgYW5kIGV4dHJhY3RlZCB0aGUgYXJ0aWNsZXMgdGhhdCBkaWQgY29udGFpbiB0aGF0IGluZm9ybWF0aW9uLiBJIGNvbGxlY3RlZCA3MiBhcnRpY2xlcyBpbiB0b3RhbC4KQWxzbywgSSBzZXBhcmF0ZWQgb3V0IGNvbHVtbnMgc28gdGhhdCBlYWNoIGNvbHVtbiBoYWQgYSBkaXN0aW5jdCBwaWVjZSBvZiBpbmZvcm1hdGlvbiBvdmVyIHRoZSBmb2xsb3dpbmcgY2F0ZWdvcmllczogYXV0aG9yIGlkLCBhdXRob3IsIGFmZmlsaWF0aW9ucywgaW5kZXgga2V5d29yZHMsIHJlZmVyZW5jZXMsIGFuZCBhdXRob3Iga2V5d29yZHMuIFRoYXQgd2F5IGxhdGVyIG9uIEkgY2FuIHdvcmsgd2l0aCB0aG9zZSBwaWVjZXMgc2VwYXJhdGVseS4KCmBgYHtyfQojIGlkZW50aWZ5aW5nIHRpbGVzLCBhYnN0cmFjdHMsIGF1dGhvciBrZXl3b3JkcyBhbmQgaW5kZXgga2V5d29yZHMgd2l0aCBteSBvd24ga2V5d29yZHMKICAjIyBrZXl3b3JkczogUmVwbGljYXRpb24gY3Jpc2lzLCByZXBsaWNhdGlvbiBjcmlzaXMsIFJlcGxpY2FiaWxpdHkgY3Jpc2lzLCByZXBsaWNhYmlsaXR5IGNyaXNpcywgUmVwcm9kdWNpYmlsaXR5IGNyaXNpcywgcmVwcm9kdWNpYmlsaXR5IGNyaXNpcwoKZGF0YS50aXRsZSA8LSBkYXRhICU+JQogIGZpbHRlcihncmVwbCgiTmV1cmFsIG5ldHdvcmt8TmV1cmFsIG5ldHdvcmtzfGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmt8YXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3MiLCB0aXRsZSwgaWdub3JlLmNhc2UgPSBUUlVFKSkKCmRhdGEuYWJzdHJhY3QgPC0gZGF0YSAlPiUKICBmaWx0ZXIoZ3JlcGwoIk5ldXJhbCBuZXR3b3JrfE5ldXJhbCBuZXR3b3Jrc3xhcnRpZmljaWFsIG5ldXJhbCBuZXR3b3JrfGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmtzIiwgYWJzdHJhY3QsIGlnbm9yZS5jYXNlID0gVFJVRSkpCgpkYXRhLmF1dGhvci5rZXl3b3JkcyA8LSBkYXRhICU+JQogIGZpbHRlcihncmVwbCgiTmV1cmFsIG5ldHdvcmt8TmV1cmFsIG5ldHdvcmtzfGFydGlmaWNpYWwgbmV1cmFsIG5ldHdvcmt8YXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3MiLCBhdXRob3Iua2V5d29yZHMsIGlnbm9yZS5jYXNlID0gVFJVRSkpCgpkYXRhLmluZGV4LmtleXdvcmRzIDwtIGRhdGEgJT4lCiAgZmlsdGVyKGdyZXBsKCJOZXVyYWwgbmV0d29ya3xOZXVyYWwgbmV0d29ya3N8YXJ0aWZpY2lhbCBuZXVyYWwgbmV0d29ya3xhcnRpZmljaWFsIG5ldXJhbCBuZXR3b3JrcyIsIGluZGV4LmtleXdvcmRzLCBpZ25vcmUuY2FzZSA9IFRSVUUpKQoKI0JJTkRJTkcgV0lUSCBUSEUgRVhUUkEgQ09MVU1OUwojcHV0dGluZyBhbGwgb2YgdGhlIGNhdGVnb3JpZXMgYmFjayB0b2dldGhlciAKZGF0YS5uZXR3b3JrcyA8LSBkby5jYWxsKCJyYmluZCIsIGxpc3QoZGF0YS50aXRsZSwgZGF0YS5hYnN0cmFjdCwgZGF0YS5hdXRob3Iua2V5d29yZHMsIGRhdGEuaW5kZXgua2V5d29yZHMpKQoKI2RlbGV0aW5nIGFueSBhcnRpY2xlcyB0aGF0IG1pZ2h0IGhhdmUgcmVwbGljYXRlZApkYXRhLm5ldHdvcmtzIDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZGlzdGluY3QoaWQsIC5rZWVwX2FsbCA9IFRSVUUpCgojc3BsaXR0aW5nIGF1dGhvci5pZCwgCiAgIyNpbiB0byBzZXBhcmF0ZSBjb2x1bW5zIHVzaW5nIHRoZSBzcGxpdHN0YWNrc2hhcGUgbGlicmFyeSwgd2hpY2ggZG9lc24ndCByZXF1aXJlIHlvdSB0byBrbm93IHRoZSB0b3RhbCBhIGNvbHVtbiBuZWVkcyB0byBiZSBzcGxpdCBpbgoKZGF0YS5uZXR3b3JrcyA8LSBjU3BsaXQoZGF0YS5uZXR3b3JrcywgImF1dGhvci5pZCIsIHNlcD0iOyIpCgpkYXRhLm5ldHdvcmtzIDwtICBjU3BsaXQoZGF0YS5uZXR3b3JrcywgImF1dGhvcnMiLCBzZXA9IiwiKQogIApkYXRhLm5ldHdvcmtzIDwtICBjU3BsaXQoZGF0YS5uZXR3b3JrcywgImFmZmlsaWF0aW9ucyIsIHNlcD0iOyIpCgpkYXRhLm5ldHdvcmtzIDwtIGNTcGxpdChkYXRhLm5ldHdvcmtzLCAiaW5kZXgua2V5d29yZHMiLCBzZXA9IjsiKQogIApkYXRhLm5ldHdvcmtzIDwtIGNTcGxpdChkYXRhLm5ldHdvcmtzLCAicmVmZXJlbmNlcyIsIHNlcD0iOyIpCgpkYXRhLm5ldHdvcmtzIDwtIGNTcGxpdChkYXRhLm5ldHdvcmtzLCAiYXV0aG9yLmtleXdvcmRzIiwgc2VwPSI7IikKYGBgCgoKVGhlIGZpc3QgZmlndXJlIHNob3dzIHdoYXQgeWVhciBpdGVtcyByZWxhdGluZyB0byBuZXVyYWwgbmV0d29ya3MgYXJlIHB1Ymxpc2hlZCBpbiBTY2llbmNlIGZyb20gMjAxMC0yMDIwLgpgYGB7cn0KI251bWJlciBvZiBpdGVtcyBieSB5ZWFyIApudW1iZXIudm9sdW1lcy5uZXR3b3JrcyAgPC0gZGF0YS5uZXR3b3JrcyAlPiUKICBjb3VudCh5ZWFyKQoKI3JlbmFtaW5nCm5hbWVzKG51bWJlci52b2x1bWVzLm5ldHdvcmtzKSA8LSBjKCJ5ZWFyIiwgIm4uaXRlbXMuYnkueWVhciIpCgojY2FsY3VsYXRpbmcgdGhlIG51bWJlciBvZiBpdGVtcyBieSBpc3N1ZQpudW1iZXIuaXNzdWVzLm5ldHdvcmtzIDwtIGRhdGEubmV0d29ya3MgJT4lIAogIGdyb3VwX2J5KHllYXIpICU+JQogIGNvdW50KGlzc3VlKQojcmVuYW1pbmcKbmFtZXMobnVtYmVyLmlzc3Vlcy5uZXR3b3JrcykgPC0gYygieWVhciIsICJpc3N1ZSIsICJuLml0ZW1zLmJ5Lmlzc3VlIikKCiNsb29raW5nIGF0IHRoZSBBUlRJQ0xFIGluZm9ybWF0aW9uIGJ5IHllYXIKaXNzdWVzLmJ5LnllYXIuYmFyLm5ldHdvcmtzIDwtIGdncGxvdChudW1iZXIudm9sdW1lcy5uZXR3b3JrcykgKwogIGdlb21fbGluZShhZXMoeD0geWVhciwgeSA9IG4uaXRlbXMuYnkueWVhciksIGNvbG9yID0gIiM1Rjg0OTUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMjAxMCwgMjAxMSwgMjAxMiwgMjAxMywgMjAxNCwgMjAxNSwgMjAxNiwgMjAxNywgMjAxOCwgMjAxOSwgMjAyMCkpICsKICMgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTApKSArCiAgeGxhYigiWWVhciIpICsgCiAgeWxhYigiTnVtYmVyIG9mIGl0ZW1zIikgKwogICNsYWJzKHRpdGxlID0gIiIpICsKICB0aGVtZV9jbGFzc2ljKCkKCmlzc3Vlcy5ieS55ZWFyLmJhci5uZXR3b3JrcwpgYGAKClRoZSBuZXh0IGZpZ3VyZSB2aXN1YWxpemVzIHRoZSBudW1iZXIgb2YgaXRlbXMgcHVibGlzaGVkIGluIFNjaWVuY2UgcmVsYXRpbmcgdG8gbmV1cmFsIG5ldHdvcmtzIGJ5IGlzc3VlLCBhbHNvIGluZGljYXRlZCBieSB5ZWFyLgpgYGB7cn0KI2NvdW50aW5nIG51bWJlciBvZiBhcnRpY2xlcyByZWxhdGVkIHRvIG5ldXJhbCBuZXR3b3JrcyBieSBpc3N1ZSAoNTQpCmlzc3Vlcy5vZi5uZXR3b3JrcyA8LSBkYXRhLm5ldHdvcmtzICU+JQogIGdyb3VwX2J5KGlzc3VlKSAlPiUKICBjb3VudChpc3N1ZSwgLmRyb3AgPSBGQUxTRSkKCiNnZXR0aW5nIGEgbGlzdCBvZiBhbGwgaXNzdWVzICg1NjkpCmFsbC5pc3N1ZXMgPC0gbnVtYmVyLmlzc3VlcyAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KC15ZWFyLCAtbi5pdGVtcy5ieS5pc3N1ZSkgJT4lCiAgbXV0YXRlKG4gPSAwKQoKI2ZpbHRlcmluZyBvdXQgdGhlIGlzc3VlcyB0aGF0IGhhdmUgbmV1cmFsIG5ldHdvcmsgaW5mb3JtYXRpb24gaW4gdGhlbSAgKDUxNS81MTIpCm51bWJlci5pc3N1ZXMubmV0d29ya3MgPC0gYWxsLmlzc3VlcyAlPiUKICBmaWx0ZXIoIShpc3N1ZSAlaW4lIGlzc3Vlcy5vZi5uZXR3b3JrcyRpc3N1ZSkpCgojYWRkaW5nIHRoZSBkYXRhYmFzZXMgYWJvdmUgdG9nZXRoZXIgKGNvdW50ZWQgYXJ0aWNsZXMgcmVsYXRlZCB0byBuZXVyYWwgbmV0d29ya3MgYW5kIHRoZSBvbmVzIHRoYXQgZG9uJ3QsIHdpdGggMCBudW1iZXJzKQp5ZWFyLmNvdW50IDwtIHJiaW5kKG51bWJlci5pc3N1ZXMubmV0d29ya3MsIGlzc3Vlcy5vZi5uZXR3b3JrcykKCmlzc3Vlcy5ieS55ZWFyLmJhciA8LSBnZ3Bsb3QoeWVhci5jb3VudCkgKwogIGdlb21fbGluZShhZXMoeD0gaXNzdWUsIHkgPSBuKSwgY29sb3IgPSAiIzQwNjM0MyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxLCAyLCAzLCA0LCA1LCA2KSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDU5MDAsIDYwMDAsIDYxMDAsIDYyMDAsIDYzMDAsIDY0MDAsIDY1MDAsIDY2MDAsIDY3MDAsIDY4MDAsIDY5MDApKSArCiAgeGxhYigiSXNzdWUgbnVtYmVyIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgaXRlbXMiKSArCiAgZ2d0aXRsZSgiRmlnIDYuIE51bWJlciBvZiBwdWJsaXNoZWQgaXRlbXMgcmVsYXRlZCB0byBuZXVyYWwgbmV0d29ya3MgYnkgaXNzdWUgaW4gU2NpZW5jZSwgMjAxMC0yMDIwIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkgKwogICMyMDEwOQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDU5NjEsIHhlbmQgPSA1OTYxLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDU5NjEsIHkgPSA2LCBsYWJlbCA9ICIyMDEwIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYwMTMsIHhlbmQgPSA2MDEzLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYwMTMsIHkgPSA2LCBsYWJlbCA9ICIyMDExIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMgogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYwNjQsIHhlbmQgPSA2MDY0LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYwNjQsIHkgPSA2LCBsYWJlbCA9ICIyMDEyIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxMwogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYxMTUsIHhlbmQgPSA2MTE1LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYxMTUsIHkgPSA2LCBsYWJlbCA9ICIyMDEzIiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYxNjYsIHhlbmQgPSA2MTY2LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYxNjYsIHkgPSA2LCBsYWJlbCA9ICIyMDE0IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYyMTcsIHhlbmQgPSA2MjE3LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYyMTcsIHkgPSA2LCBsYWJlbCA9ICIyMDE1IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNgogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYyNjgsIHhlbmQgPSA2MjY4LCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYyNjgsIHkgPSA2LCBsYWJlbCA9ICIyMDE2IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxNwogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYzMjAsIHhlbmQgPSA2MzIwLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYzMjAsIHkgPSA2LCBsYWJlbCA9ICIyMDE3IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxOAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDYzNzEsIHhlbmQgPSA2MzcxLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDYzNzEsIHkgPSA2LCBsYWJlbCA9ICIyMDE4IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAxOQogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDY0MjIsIHhlbmQgPSA2NDIyLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDY0MjIsIHkgPSA2LCBsYWJlbCA9ICIyMDE5IiwgY29sb3IgPSAiIzk5QTc5OSIpICsKICAjMjAyMAogIGdncGxvdDI6OmFubm90YXRlKCJzZWdtZW50IiwgeCA9IDY0NzMsIHhlbmQgPSA2NDczLCB5ID0gMCwgeWVuZCA9IDUuNywgbGluZXR5cGUgPSAyLCBjb2xvciA9ICIjOTlBNzk5IikgKwogIGdncGxvdDI6OmFubm90YXRlKCJ0ZXh0IiwgeCA9IDY0NzMsIHkgPSA2LCBsYWJlbCA9ICIyMDIwIiwgY29sb3IgPSAiIzk5QTc5OSIpCiAgCmlzc3Vlcy5ieS55ZWFyLmJhciArIHRoZW1lX2NsYXNzaWMoKQpgYGAKCk5leHQgaXMgYSBoaXN0b2dyYW0gb2YgbnVtYmVyIG9mIGNpdGF0aW9ucyByZWNpZXZlZCBieSBuZXVyYWwgbmV0d29yayBpdGVtcyBmcm9tIFNjaWVuY2UgMjAxMC0yMDIwLgpgYGB7cn0KI2Rlc2NyaXB0aXZlIHZpc3VhbGl6YXRpb24KICAjIyBvbmU6IGhpc3RvZ3JhbSBvZiB0aGUgY2l0YXRpb24sIGJpbnMgd2l0aCAzMCBjb3VudHMKY2l0YXRpb24uaGlzdCA8LSBnZ3Bsb3QoZGF0YS5uZXR3b3JrcywgYWVzKHg9Y2l0ZWQuYnkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbCA9ICIjNDA2MzQzIiwgYmlud2lkdGg9IDMwLCBjZW50ZXIgPSAwLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxMDAsIDIwMCwgMzAwLCA0MDAsIDUwMCwgNjAwLCA3MDAsIDgwMCwgOTAwLCAxMDAwLCAxMTAwLCAxMjAwLCAxMzAwLCAxNDAwLCAxNTAwLCAxNjAwLCAxNzAwLCAxODAwLCAxOTAwKSkgKwogIHhsYWIoIkNpdGF0aW9uIGNvdW50cyIpICsgCiAgeWxhYigiTnVtYmVyIG9mIGFydGljbGVzIikgKwogIGxhYnModGl0bGUgPSAiRmlnIDguIERpc3RyaWJ1dGlvbiBvZiBhbW91bnQgb2YgY2l0YXRpb25zIHJlY2VpdmVkIGJ5IG5ldXJhbCBuZXR3b3JrIGl0ZW1zIikKCmNpdGF0aW9uLmhpc3QgKyB0aGVtZV9jbGFzc2ljKCkKYGBgCgpUbyB2aWV3IHRoZSBoaXN0b2dyYW0gZGlzdHJpYnV0aW9uIG1vcmUgY2xlYXJseSwgSSBhbHNvIHJhbiBhIHZlcnNpb24gdGhhdCBleGNsdWRlZCB0aGUgb3V0bGllcnMgKHdoaWNoIEkgY2F0ZWdvcml6ZXMgYXMgb3ZlciA1MDAgY2l0YXRpb25zKQpgYGB7cn0KI3R3bzogdmlzdWFsaXphdGlvbiBvZiB0aGUgY2l0YXRpb24gY291bnRzIGV4Y2x1ZGluZyBvdXRsaWVycyAoPDUwMCkKICAjIyBiaW53aWR0aCAxMApkYXRhLm5ldHdvcmtzLmNpdGF0aW9uLm1vc3QgPC0gZGF0YS5uZXR3b3JrcyAlPiUKICBmaWx0ZXIoY2l0ZWQuYnkgPCA1MDApCgpjaXRhdGlvbi5oaXN0Lm1vc3QgPC0gZ2dwbG90KGRhdGEubmV0d29ya3MuY2l0YXRpb24ubW9zdCwgYWVzKHg9Y2l0ZWQuYnkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAzMCwgZmlsbCA9ICIjNDA2MzQzIikgKwogICAjIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDEwLCA1MCwgMTAwLCAxNTAsIDIwMCwgMjUwLCAzMDAsIDM1MCwgNDAwLCAKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0NTAsIDUwMCwgNTUwLCA2MDAsIDY1MCwgNzAwLCA3NTAsIDgwMCkpICsKICB4bGFiKCJDaXRhdGlvbiBjb3VudHMsIHdpdGhvdXQgb3V0bGllcnMiKSArIAogIHlsYWIoIk51bWJlciBvZiBhcnRpY2xlcyIpICsKICBsYWJzKHRpdGxlID0gIkZpZyA5LiBEaXN0cmlidXRpb24gb2YgYW1tb3VudCBvZiBjaXRhdGlvbnMgcmVjaWV2ZWQgYnkgbmV1cmFsIG5ldHdvcmsgaXRlbXMsIGV4Y2x1ZGluZyBvdXRsaWVycyAoNTAwKSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkpCgpjaXRhdGlvbi5oaXN0Lm1vc3QgKyB0aGVtZV9jbGFzc2ljKCkKYGBgCgpUaGUgZm9sbG93aW5nIHBpZSBjaGFydCBjYXRlZ29yaXplcyB3aGF0IGl0ZW1zIGhhdmUgb3IgZG8gbm90IGhhdmUgYWJzdHJhY3QgaW5mb3JtYXRpb24uCmBgYHtyfQojcGllIGNoYXJ0IG9mIHRoZSBwZXJjZW50YWdlIG9mIGFydGljbGVzIHdpdGggbm8gYXJ0aWNsZXMKCiNjaGVja2luZyBob3cgbWFueSBhcnRpY2xlcyBhcmUgbWlzc2luZyBhYnN0cmFjdHMKICAjdG90YWwgYXJ0aWNsZXMgbWlzc2luZyBhYnN0cmFjdHMgPSAxMzIxMApkYXRhLm5uLm5vLmFic3RyYWN0IDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZmlsdGVyKGlzLm5hKGFic3RyYWN0KSkgJT4lICNmaWx0ZXJpbmcgdGhvc2Ugcm93cyBpbiBhYnN0cmFjdCB0aGF0IGhhdmUgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIk5vIikKCmRhdGEubm4ueWVzLmFic3RyYWN0IDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZmlsdGVyKCEoaWQgJWluJSBkYXRhLm5uLm5vLmFic3RyYWN0JGlkKSkgJT4lICNmaWx0ZXJpbmcgb3V0IHRob3NlIGFydGljbGVzIGFscmVhZHkgY2F0ZWdvcml6ZWQgYXMgTkEKICBtdXRhdGUoaGFzLmFic3RyYWN0ID0gIlllcyIpCgpkYXRhLm5uLmFic3RyYWN0LmJvdGggPC0gcmJpbmQoZGF0YS5ubi5uby5hYnN0cmFjdCwgZGF0YS5ubi55ZXMuYWJzdHJhY3QpCgpkYXRhLm5uLmFic3RyYWN0cyA8LSBkYXRhLm5uLmFic3RyYWN0LmJvdGggJT4lCiAgZ3JvdXBfYnkoaGFzLmFic3RyYWN0KSAlPiUKICBjb3VudChoYXMuYWJzdHJhY3QpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyID0gKDEwMCpuKS9zdW0obikpCgpkYXRhLm5uLmFic3RyYWN0cyRwZXIgPC0gcm91bmQoZGF0YS5ubi5hYnN0cmFjdHMkcGVyKQoKZ2dwbG90KGRhdGEubm4uYWJzdHJhY3RzLCBhZXMoeD0iIiwgeSA9IGhhcy5hYnN0cmFjdCwgZmlsbCA9IGhhcy5hYnN0cmFjdCwgcGFsZXR0ZSA9ICJCdUduIikpICsKICAgZ2VvbV9jb2woKSArCiAgdGhlbWVfdm9pZCgpICsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAicGFsNSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHBlciwiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpKSArCiAgZ2d0aXRsZSgiRmlnIDEwLiBQZXJjZW50YWdlcyBvZiBpdGVtcyBhYm91dCBuZXVyYWwgbmV0d29ya3MgCiAgICAgICAgICB3aXRoIG9yIHdpdGhvdXQgYWJzdHJhY3RzIGluIFNjaWVuY2UgMjAxMC0yMDIwIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkhhcyBBYnN0cmFjdCIpKQpgYGAKClRoZSBuZXh0IGZpZ3VyZSBpcyBhIGRpc3RyaWJ1dGlvbiBvZiBkb2N1bWVudCB0eXBlcyBhYm91dCBuZXVyYWwgbmV0d29ya3MgYW5kIHdoZXRoZXIgdGhleSBoYXZlIGFic3RyYWN0cyBpbiBTY2llbmNlIDIwMTAtMjAyMC4KYGBge3J9CiNjaGVja2luZyBieSBkb2N1bWVudCB0eXBlIHdoYXQgdGhpbmdzIGFyZSBtaXNzaW5nIGFic3RyYWN0cwpubi5hYnN0cmFjdC50eXBlcyA8LSBnZ3Bsb3QoZGF0YS5ubi5hYnN0cmFjdC5ib3RoLCBhZXMoeCA9IGRvY3VtZW50LnR5cGUsIGZpbGwgPSBoYXMuYWJzdHJhY3QsIHBhbGV0dGUgPSAiQnVHbiIpKSArCiAgZ2VvbV9iYXIoKSArCiAgeGxhYigiS2luZHMgb2YgZG9jdW1lbnRzIikgKyAKICB5bGFiKCJBbW91bnQgd2l0aCBvciB3aXRob3V0IGFic3RyYWN0IGluZm9ybWF0aW9uIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCdUduIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkhhcyBBYnN0cmFjdCIpKSArCiAgZ2d0aXRsZSgiRmlnIDExLiBEaXN0cmlidXRpb24gb2YgZG9jdW1lbnQgdHlwZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzIGFuZCB3ZXRoZXIgCiAgICAgICAgICB0aGV5IGhhdmUgYWJzdHJhY3RzIGluIFNjaWVuY2UgMjAxMC0yMDIwIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKCiN0aWx0aW5nIHRoZSB0ZXh0IHNvIGl0IGlzIHJlYWRhYmxlIGFuZCBtb3ZpbmcgZG93bndhcmRzCm5uLmFic3RyYWN0LnR5cGVzICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgpUaGUgbmV4dCBmaWd1cmUgaXMgYSB3b3JkIGNsb3VkIG9mIHRoZSBtb3N0IGNvbW1vbiB3b3JkcyBpbiB0aGUgYWJzdHJhY3QsIGluY2x1ZGluZyBjb21tb24gd29yZHMuIApgYGB7cn0KI21ha2luZyBhIGxvbmcgbGlzdCBvZiBhbGwgdGhlIGtleXdvcmRzIHVzZWQgaW4gYXJ0aWNsZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzCmluZGV4LmtleXdvcmRzIDwtIGRhdGEubmV0d29ya3MgJT4lCiAgc2VsZWN0KGluZGV4LmtleXdvcmRzXzAxOmluZGV4LmtleXdvcmRzXzY2LCBpZCkKCmluZGV4LmtleXdvcmRzID0gbWVsdChpbmRleC5rZXl3b3JkcyxpZC52YXJzPWMoImlkIikpCgojbWFraW5nIGV2ZXJ5dGhpbmcgbG93ZXJjYXNlCmluZGV4LmtleXdvcmRzJHZhbHVlID0gdG9sb3dlcihpbmRleC5rZXl3b3JkcyR2YWx1ZSkKCmluZGV4LmtleXdvcmRzIDwtIGluZGV4LmtleXdvcmRzICU+JQogIHNlbGVjdCgtaWQsIC12YXJpYWJsZSkgJT4lCiAgZHJvcF9uYSh2YWx1ZSkgJT4lCiAgY291bnQodmFsdWUpCgp3b3JkY2xvdWQod29yZHMgPSBpbmRleC5rZXl3b3JkcyR2YWx1ZSwgZnJlcSA9IGluZGV4LmtleXdvcmRzJG4sIG1pbi5mcmVxID0gNSwKICAgICAgICAgIG1heC53b3Jkcz0yMDAsIHJhbmRvbS5vcmRlcj1GQUxTRSwgcm90LnBlcj0wLjM1LAogICAgICAgICAgY29sb3JzPWJyZXdlci5wYWwoOCwgIkRhcmsyIiksIHNjYWxlPWMoMi4wLDAuMjUpKQpgYGAKClRvIG1vcmUgY2xlYXJseSBzZWUgdGhlIHdvcmRzIG9mIGludGVyZXN0LCBJIGV4Y2x1ZGVkIHNvbWUgb2YgdGhlIHdvcmRzIHRoYXQgYXJlIG1vcmUgY29tbW9uIGluIHRoZSBFbmdsaXNoIGxhbmd1YWdlIGFuZCB0aGVyZWZvcmUgbWlnaHQgYmUgbGVzcyBpbmRpY2F0aXZlIG9mIHdoYXQgdGhlIGFic3RyYWN0cyBhcmUgYWJvdXQuIFRoZSBrZXl3b3JkcyBJIGV4Y2x1ZGVkIHdlcmU6IHRoZSwgb2YsIGFuZCwgaW4sIGEsIHRvLCBmb3IsIHRoYXQsIHdlLCBpcywgYnksIHdpdGgsIHRoaXMsIGFyZSwgb24sIGFuLCBjYW4sIGZyb20sIGFsbCwgwqksIGJlLCB3aGljaCwgaG93LCBvciwgb3VyLCBpdC4KYGBge3J9CiNtYWtpbmcgd29yZGNsb3VkIG9mIHRoZSBhYnN0cmFjdCBpbmZvcm1hdGlvbgphYnN0cmFjdC53b3JkcyA8LSBkYXRhLm5ldHdvcmtzICU+JQogIHNlbGVjdChpZCwgYWJzdHJhY3QpICU+JQogIGRyb3BfbmEoYWJzdHJhY3QpCgojdGFraW5nIGF3YXkgcHVuY3R1YXRpb24KYWJzdHJhY3Qud29yZHMkYWJzdHJhY3QgPC0gZ3N1YignW1s6cHVuY3Q6XSBdKycsJyAnLCBhcy5jaGFyYWN0ZXIoYWJzdHJhY3Qud29yZHMkYWJzdHJhY3QpKQogIAojbWFraW5nIHdob2xlIHRleHQgbG93ZXJjYXNlCmFic3RyYWN0LndvcmRzJGFic3RyYWN0ID0gdG9sb3dlcihhYnN0cmFjdC53b3JkcyRhYnN0cmFjdCkKCiNzZXBhcmF0aW5nIGNvbHVtbiBvdXQgaW4gdG8gaW5kaXZpZHVhbCB3b3JkcwphYnN0cmFjdC53b3JkcyA8LSBjU3BsaXQoYWJzdHJhY3Qud29yZHMsICJhYnN0cmFjdCIsIHNlcD0iICIpCgojdHJpbW1pbmcgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZQp0cmltd3NfZGYgPC0gZnVuY3Rpb24oeCwgLi4uKXsKICB4W10gPC0gbGFwcGx5KHgsIHRyaW13cywgLi4uKQogIHgKfQphYnN0cmFjdC53b3JkcyA8LSB0cmltd3NfZGYoYWJzdHJhY3Qud29yZHMpCgojY29tYmluaW5nIGluIHRvIG9uZSBjb2x1bW4KYWJzdHJhY3Qud29yZHMgPSBtZWx0KGFic3RyYWN0LndvcmRzLCBpZC52YXJzPWMoImlkIikpCgojY291bnRpbmcgdGhlIG51bWJlciBvZiB3b3JkcwphYnN0cmFjdC53b3JkcyA8LSBhYnN0cmFjdC53b3JkcyAlPiUKICBzZWxlY3QoLWlkLCAtdmFyaWFibGUpICU+JQogIGRyb3BfbmEodmFsdWUpICU+JQogIGNvdW50KHZhbHVlKQoKI21ha2luZyBhIHdvcmQgY2xvdWQgaW5jbHVkaW5nIGFsbCB0aGUgd29yZHMKd29yZGNsb3VkKHdvcmRzID0gYWJzdHJhY3Qud29yZHMkdmFsdWUsIGZyZXEgPSBhYnN0cmFjdC53b3JkcyRuLCBtaW4uZnJlcSA9IDMsCiAgICAgICAgICBtYXgud29yZHM9MjAwLCByYW5kb20ub3JkZXI9RkFMU0UsIHJvdC5wZXI9MC4zNSwgc2NhbGU9Yyg1LjAsMC41KSwKICAgICAgICAgIGNvbG9ycz1icmV3ZXIucGFsKDgsICJEYXJrMiIpKQoKI3JlbW92aW5nIGNvbW1vbiB3b3JkcwphYnN0cmFjdC53b3JkcyA8LSBhYnN0cmFjdC53b3Jkc1shZ3JlcGwoInRoZXxvZnxhbmR8aW58YXx0b3xmb3J8dGhhdHx3ZXxpc3xieXx3aXRofHRoaXN8YXJlfG9ufGFufGNhbnxmcm9tfGFsbHzCqXxiZXx3aGljaHxob3d8b3J8b3VyfGl0IiwgYWJzdHJhY3Qud29yZHMkdmFsdWUpLF0KCiNtYWtpbmcgd29yZCBjbG91ZAp3b3JkY2xvdWQod29yZHMgPSBhYnN0cmFjdC53b3JkcyR2YWx1ZSwgZnJlcSA9IGFic3RyYWN0LndvcmRzJG4sIG1pbi5mcmVxID0gMywKICAgICAgICAgbWF4LndvcmRzPTIwMCwgcmFuZG9tLm9yZGVyPUZBTFNFLCByb3QucGVyPTAuMzUsCiAgICAgICAgY29sb3JzPWJyZXdlci5wYWwoOCwgIkRhcmsyIiksIHNjYWxlPWMoMy4wLDAuMjUpKQpgYGAKCkkgc2VsZWN0ZWQgNCBhcnRpY2xlcyByYW5kb21seSB0byBxdWFsaXRhdGl2ZWx5IGNvZGUuIFR3byB3ZXJlIHRvdGFsbHkgcmFuZG9tIGFuZCBJIGdvdDoKCeKBgwkgTmV1cmFsIHNjZW5lIHJlcHJlc2VudGF0aW9uIGFuZCByZW5kZXJpbmcsIDIwMTguIFZvbCAzNjAsIGlzc3VlIDYzOTQuIGRvaTogMTAuMTEyNi9zY2llbmNlLmFhcjYxNzAKCeKBgwlUaGUgYmlvY2hlbWljYWwgYmFzaXMgb2YgbWljcm9STkEgdGFyZ2V0aW5nIGVmZmljYWN5LCAyMDE5LiBWb2wgMzY2LiBkb2k6IDEwLjExMjYvc2NpZW5jZS5hYXYxNzQxCk9uZSB3YXMgZnJvbSB0aGUgdG9wIDI1JSBvZiBjaXRhdGlvbnMgcmVjZWl2ZWQgKG1vcmUgdGhhbiAxNzEuNSBjaXRhdGlvbnMpCgnigYMJVGVycmVzdHJpYWwgZ3Jvc3MgY2FyYm9uIGRpb3hpZGUgdXB0YWtlOiBHbG9iYWwgZGlzdHJpYnV0aW9uIGFuZCBjb3ZhcmlhdGlvbiB3aXRoIGNsaW1hdGUuIGRvaTogMTAuMTEyNi9zY2llbmNlLjExODQ5ODQKT25lIHdhcyByYW5kb21seSBzZWxlY3RlZCBmcm9tIHRoZSB5ZWFyIHdpdGggdGhlIG1vc3QgYXJ0aWNsZXMgYWJvdXQgbmV1cmFsIG5ldHdvcmtzICgyMDE5KQoJ4oGDCU1hY2hpbmUgbGVhcm5pbmcgdHJhbnNmb3JtcyBob3cgbWljcm9zdGF0ZXMgYXJlIHNhbXBsZWQsIDIwMTkuIFZvbCAzNjUuIElzc3VlIDY0NTcuIGRvaTogMTAuMTEyNi9zY2llbmNlLmFheTI1NjgKQXMgYSBub3RlLCB0aGlzIHdpbGwgcmV0dXJuIGRpZmZlcmVudCBhcnRpY2xlcyBldmVyeSB0aW1lIGl0IGlzIHJ1bi4gSSd2ZSBzZWxlY3RlZCB0aGUgYXJ0aWNsZXMgdGhhdCBhcHBlYXJlZCB0aGUgZmlyc3QgdGltZS4KYGBge3J9CiNyYW5kb21seSBzZWxlY3RpbmcgYXJ0aWNsZXMgdG8gY2xvc2UgcmVhZAogICMjbm90ZSwgdGhpcyB3aWxsIHJldHVybiBkaWZmZXJlbnQgYXJ0aWNsZXMgZXZlcnkgdGltZSBpdCBpcyBydW4uIEkndmUgc2VsZWN0ZWQgdGhlIGFydGljbGVzIHRoYXQgYXBwZWFyZWQgdGhlIGZpcnN0IHRpbWUuCgojcmFuZG9tbHkgc2VsZWN0aW5nIDIgYXJ0aWNsZXMgZnJvbSB0aGUgd2hvbGUgbmV0d29ya3MgZGF0YWJhc2UKc2FtcGxlX24oZGF0YS5uZXR3b3JrcywgMikKICAjc2VsZWN0ZWQ6IE5ldXJhbCBzY2VuZSByZXByZXNlbnRhdGlvbiBhbmQgcmVuZGVyaW5nLCAyMDE4LiBWb2wgMzYwLCBpc3N1ZSA2Mzk0LiBkb2k6IDEwLjExMjYvc2NpZW5jZS5hYXI2MTcwCiAgI3NlbGVjdGVkOiBUaGUgYmlvY2hlbWljYWwgYmFzaXMgb2YgbWljcm9STkEgdGFyZ2V0aW5nIGVmZmljYWN5LCAyMDE5LiBWb2wgMzY2LiBkb2k6IDEwLjExMjYvc2NpZW5jZS5hYXYxNzQxCgojcmFuZG9tbHkgc2VsZWN0aW5nIDEgYXJ0aWNsZSB3aXRoaW4gdGhlIHRvcCAyNSUgbnVtYmVyIG9mIGNpdGF0aW9ucwogICMjIGV4dHJhY3RpbmcgdGhlIHF1YW50aWxlcyBvZiB0aGUgZGF0YXNldCwgdXBwZXIgNzUlID0gMTcxLjUKcXVhbnRpbGUoZGF0YS5uZXR3b3JrcyRjaXRlZC5ieSwgbmEucm09VFJVRSkKCmRhdGEubmV0d29ya3MudG9wLjc1cGVyIDwtIGRhdGEubmV0d29ya3MgJT4lCiAgZmlsdGVyKGNpdGVkLmJ5ID4gMTcxLjUpCgpzYW1wbGVfbihkYXRhLm5ldHdvcmtzLnRvcC43NXBlciwxKQogICNzZWxlY3RlZDogVGVycmVzdHJpYWwgZ3Jvc3MgY2FyYm9uIGRpb3hpZGUgdXB0YWtlOiBHbG9iYWwgZGlzdHJpYnV0aW9uIGFuZCBjb3ZhcmlhdGlvbiB3aXRoIGNsaW1hdGUuIGRvaTogMTAuMTEyNi9zY2llbmNlLjExODQ5ODQKCiNyYW5kb21seSBzZWxlY3RpbmcgMSBhcnRpY2xlIGZyb20gMjAxOSAodGhlIHllYXIgd2l0aCB0aGUgbW9zdCBhcnRpY2xlcyBwdWJsaXNoZWQpCmRhdGEubmV0d29ya3MuMjAxOSA8LSBkYXRhLm5ldHdvcmtzICU+JQogIGZpbHRlcih5ZWFyID09ICIyMDE5IikKCnNhbXBsZV9uKGRhdGEubmV0d29ya3MuMjAxOSwgMSkKICAjc2VsZWN0ZWQ6IE1hY2hpbmUgbGVhcm5pbmcgdHJhbnNmb3JtcyBob3cgbWljcm9zdGF0ZXMgYXJlIHNhbXBsZWQsIDIwMTkuIFZvbCAzNjUuIElzc3VlIDY0NTcuIGRvaTogMTAuMTEyNi9zY2llbmNlLmFheTI1NjgKYGBg